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;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeDivision (operand *, operand *);
49 operand *geniCodeAssign (operand *, operand *, int);
50 operand *geniCodeArray (operand *, operand *,int);
51 operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
57 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
58 /* forward definition of ic print functions */
59 PRINTFUNC (picGetValueAtAddr);
60 PRINTFUNC (picSetValueAtAddr);
61 PRINTFUNC (picAddrOf);
62 PRINTFUNC (picGeneric);
63 PRINTFUNC (picGenericOne);
65 PRINTFUNC (picAssign);
69 PRINTFUNC (picJumpTable);
70 PRINTFUNC (picInline);
71 PRINTFUNC (picReceive);
72 PRINTFUNC (picDummyRead);
73 PRINTFUNC (picCritical);
74 PRINTFUNC (picEndCritical);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
121 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
122 {CRITICAL, "critical_start", picCritical, NULL},
123 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
126 /*-----------------------------------------------------------------*/
127 /* checkConstantRange: check a constant against the type */
128 /*-----------------------------------------------------------------*/
131 /* pedantic=0: allmost anything is allowed as long as the absolute
132 value is within the bit range of the type, and -1 is treated as
133 0xf..f for unsigned types (e.g. in assign)
134 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
135 pedantic>1: "char c=200" is not allowed (evaluates to -56)
138 void checkConstantRange(sym_link *ltype, value *val, char *msg,
145 max = pow ((double)2.0, (double)bitsForType(ltype));
147 if (SPEC_LONG(val->type)) {
148 if (SPEC_USIGN(val->type)) {
149 v=SPEC_CVAL(val->type).v_ulong;
151 v=SPEC_CVAL(val->type).v_long;
154 if (SPEC_USIGN(val->type)) {
155 v=SPEC_CVAL(val->type).v_uint;
157 v=SPEC_CVAL(val->type).v_int;
163 // this could be a good idea
164 if (options.pedantic)
168 if (SPEC_NOUN(ltype)==FLOAT) {
173 if (!SPEC_USIGN(val->type) && v<0) {
175 if (SPEC_USIGN(ltype) && (pedantic>1)) {
181 // if very pedantic: "char c=200" is not allowed
182 if (pedantic>1 && !SPEC_USIGN(ltype)) {
183 max = max/2 + negative;
190 #if 0 // temporary disabled, leaving the warning as a reminder
192 SNPRINTF (message, sizeof(message), "for %s %s in %s",
193 SPEC_USIGN(ltype) ? "unsigned" : "signed",
194 nounName(ltype), msg);
195 werror (W_CONST_RANGE, message);
203 /*-----------------------------------------------------------------*/
204 /* operandName - returns the name of the operand */
205 /*-----------------------------------------------------------------*/
207 printOperand (operand * op, FILE * file)
224 opetype = getSpec (operandType (op));
225 if (SPEC_NOUN (opetype) == V_FLOAT)
226 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
228 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
229 printTypeChain (operandType (op), file);
236 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}" , */
237 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
239 OP_LIVEFROM (op), OP_LIVETO (op),
240 OP_SYMBOL (op)->stack,
241 op->isaddr, OP_SYMBOL (op)->isreqv,
242 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
243 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
247 printTypeChain (operandType (op), file);
248 if (SPIL_LOC (op) && IS_ITEMP (op))
249 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
254 /* if assigned to registers */
255 if (OP_SYMBOL (op)->nRegs)
257 if (OP_SYMBOL (op)->isspilt)
259 if (!OP_SYMBOL (op)->remat)
260 if (OP_SYMBOL (op)->usl.spillLoc)
261 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
262 OP_SYMBOL (op)->usl.spillLoc->rname :
263 OP_SYMBOL (op)->usl.spillLoc->name));
265 fprintf (file, "[err]");
267 fprintf (file, "[remat]");
273 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
274 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
279 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
280 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
281 /* if assigned to registers */
282 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
286 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
287 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
288 OP_SYMBOL (op)->regs[i]->name :
297 printTypeChain (op->operand.typeOperand, file);
303 fprintf (file, "\n");
308 /*-----------------------------------------------------------------*/
309 /* print functions */
310 /*-----------------------------------------------------------------*/
311 PRINTFUNC (picGetValueAtAddr)
314 printOperand (IC_RESULT (ic), of);
317 printOperand (IC_LEFT (ic), of);
323 PRINTFUNC (picSetValueAtAddr)
327 printOperand (IC_LEFT (ic), of);
328 fprintf (of, "] = ");
329 printOperand (IC_RIGHT (ic), of);
333 PRINTFUNC (picAddrOf)
336 printOperand (IC_RESULT (ic), of);
337 if (IS_ITEMP (IC_LEFT (ic)))
340 fprintf (of, " = &[");
341 printOperand (IC_LEFT (ic), of);
344 if (IS_ITEMP (IC_LEFT (ic)))
345 fprintf (of, " offsetAdd ");
348 printOperand (IC_RIGHT (ic), of);
350 if (IS_ITEMP (IC_LEFT (ic)))
356 PRINTFUNC (picJumpTable)
361 fprintf (of, "%s\t", s);
362 printOperand (IC_JTCOND (ic), of);
364 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
365 sym = setNextItem (IC_JTLABELS (ic)))
366 fprintf (of, "\t\t\t%s\n", sym->name);
369 PRINTFUNC (picGeneric)
372 printOperand (IC_RESULT (ic), of);
374 printOperand (IC_LEFT (ic), of);
375 fprintf (of, " %s ", s);
376 printOperand (IC_RIGHT (ic), of);
380 PRINTFUNC (picGenericOne)
385 printOperand (IC_RESULT (ic), of);
391 fprintf (of, "%s ", s);
392 printOperand (IC_LEFT (ic), of);
395 if (!IC_RESULT (ic) && !IC_LEFT (ic))
398 if (ic->op == SEND || ic->op == RECEIVE) {
399 fprintf(of,"{argreg = %d}",ic->argreg);
407 printOperand (IC_RESULT (ic), of);
409 printOperand (IC_LEFT (ic), of);
410 printOperand (IC_RIGHT (ic), of);
415 PRINTFUNC (picAssign)
419 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
422 printOperand (IC_RESULT (ic), of);
424 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
427 fprintf (of, " %s ", s);
428 printOperand (IC_RIGHT (ic), of);
435 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
441 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
448 printOperand (IC_COND (ic), of);
451 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
454 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
456 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
460 PRINTFUNC (picInline)
462 fprintf (of, "%s", IC_INLINE (ic));
465 PRINTFUNC (picReceive)
467 printOperand (IC_RESULT (ic), of);
468 fprintf (of, " = %s ", s);
469 printOperand (IC_LEFT (ic), of);
473 PRINTFUNC (picDummyRead)
476 fprintf (of, "%s ", s);
477 printOperand (IC_RIGHT (ic), of);
481 PRINTFUNC (picCritical)
485 printOperand (IC_RESULT (ic), of);
487 fprintf (of, "(stack)");
488 fprintf (of, " = %s ", s);
492 PRINTFUNC (picEndCritical)
495 fprintf (of, "%s = ", s);
497 printOperand (IC_RIGHT (ic), of);
499 fprintf (of, "(stack)");
503 /*-----------------------------------------------------------------*/
504 /* piCode - prints one iCode */
505 /*-----------------------------------------------------------------*/
507 piCode (void *item, FILE * of)
515 icTab = getTableEntry (ic->op);
516 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
517 ic->filename, ic->lineno,
518 ic->seq, ic->key, ic->depth, ic->supportRtn);
519 icTab->iCodePrint (of, ic, icTab->printName);
525 printiCChain(ic,stdout);
527 /*-----------------------------------------------------------------*/
528 /* printiCChain - prints intermediate code for humans */
529 /*-----------------------------------------------------------------*/
531 printiCChain (iCode * icChain, FILE * of)
538 for (loop = icChain; loop; loop = loop->next)
540 if ((icTab = getTableEntry (loop->op)))
542 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
543 loop->filename, loop->lineno,
544 loop->seq, loop->key, loop->depth, loop->supportRtn);
546 icTab->iCodePrint (of, loop, icTab->printName);
552 /*-----------------------------------------------------------------*/
553 /* newOperand - allocate, init & return a new iCode */
554 /*-----------------------------------------------------------------*/
560 op = Safe_alloc ( sizeof (operand));
566 /*-----------------------------------------------------------------*/
567 /* newiCode - create and return a new iCode entry initialised */
568 /*-----------------------------------------------------------------*/
570 newiCode (int op, operand * left, operand * right)
574 ic = Safe_alloc ( sizeof (iCode));
576 ic->seqPoint = seqPoint;
578 ic->filename = filename;
580 ic->level = scopeLevel;
582 ic->key = iCodeKey++;
584 IC_RIGHT (ic) = right;
589 /*-----------------------------------------------------------------*/
590 /* newiCode for conditional statements */
591 /*-----------------------------------------------------------------*/
593 newiCodeCondition (operand * condition,
599 if (IS_VOID(operandType(condition))) {
600 werror(E_VOID_VALUE_USED);
603 ic = newiCode (IFX, NULL, NULL);
604 IC_COND (ic) = condition;
605 IC_TRUE (ic) = trueLabel;
606 IC_FALSE (ic) = falseLabel;
610 /*-----------------------------------------------------------------*/
611 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
612 /*-----------------------------------------------------------------*/
614 newiCodeLabelGoto (int op, symbol * label)
618 ic = newiCode (op, NULL, NULL);
622 IC_RIGHT (ic) = NULL;
623 IC_RESULT (ic) = NULL;
627 /*-----------------------------------------------------------------*/
628 /* newiTemp - allocate & return a newItemp Variable */
629 /*-----------------------------------------------------------------*/
637 SNPRINTF (buffer, sizeof(buffer), "%s", s);
641 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
644 itmp = newSymbol (buffer, 1);
645 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
651 /*-----------------------------------------------------------------*/
652 /* newiTempLabel - creates a temp variable label */
653 /*-----------------------------------------------------------------*/
655 newiTempLabel (char *s)
659 /* check if this alredy exists */
660 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
665 itmplbl = newSymbol (s, 1);
669 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
670 itmplbl = newSymbol (buffer, 1);
675 itmplbl->key = labelKey++;
676 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
680 /*-----------------------------------------------------------------*/
681 /* newiTempPreheaderLabel - creates a new preheader label */
682 /*-----------------------------------------------------------------*/
684 newiTempPreheaderLabel ()
688 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
689 itmplbl = newSymbol (buffer, 1);
693 itmplbl->key = labelKey++;
694 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
699 /*-----------------------------------------------------------------*/
700 /* initiCode - initialises some iCode related stuff */
701 /*-----------------------------------------------------------------*/
708 /*-----------------------------------------------------------------*/
709 /* copyiCode - make a copy of the iCode given */
710 /*-----------------------------------------------------------------*/
712 copyiCode (iCode * ic)
714 iCode *nic = newiCode (ic->op, NULL, NULL);
716 nic->lineno = ic->lineno;
717 nic->filename = ic->filename;
718 nic->block = ic->block;
719 nic->level = ic->level;
720 nic->parmBytes = ic->parmBytes;
722 /* deal with the special cases first */
726 IC_COND (nic) = operandFromOperand (IC_COND (ic));
727 IC_TRUE (nic) = IC_TRUE (ic);
728 IC_FALSE (nic) = IC_FALSE (ic);
732 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
733 IC_JTLABELS (nic) = IC_JTLABELS (ic);
738 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
739 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
743 IC_INLINE (nic) = IC_INLINE (ic);
747 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
751 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
752 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
753 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
759 /*-----------------------------------------------------------------*/
760 /* getTableEntry - gets the table entry for the given operator */
761 /*-----------------------------------------------------------------*/
763 getTableEntry (int oper)
767 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
768 if (oper == codeTable[i].icode)
769 return &codeTable[i];
774 /*-----------------------------------------------------------------*/
775 /* newiTempOperand - new intermediate temp operand */
776 /*-----------------------------------------------------------------*/
778 newiTempOperand (sym_link * type, char throwType)
781 operand *op = newOperand ();
785 itmp = newiTemp (NULL);
787 etype = getSpec (type);
789 if (IS_LITERAL (etype))
792 /* copy the type information */
794 itmp->etype = getSpec (itmp->type = (throwType ? type :
795 copyLinkChain (type)));
796 if (IS_LITERAL (itmp->etype))
798 SPEC_SCLS (itmp->etype) = S_REGISTER;
799 SPEC_OCLS (itmp->etype) = reg;
802 op->operand.symOperand = itmp;
803 op->key = itmp->key = ++operandKey;
807 /*-----------------------------------------------------------------*/
808 /* operandType - returns the type chain for an operand */
809 /*-----------------------------------------------------------------*/
811 operandType (operand * op)
813 /* depending on type of operand */
818 return op->operand.valOperand->type;
821 return op->operand.symOperand->type;
824 return op->operand.typeOperand;
826 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
827 " operand type not known ");
828 assert (0); /* should never come here */
829 /* Just to keep the compiler happy */
830 return (sym_link *) 0;
834 /*-----------------------------------------------------------------*/
835 /* isParamterToCall - will return 1 if op is a parameter to args */
836 /*-----------------------------------------------------------------*/
838 isParameterToCall (value * args, operand * op)
842 wassert (IS_SYMOP(op));
847 isSymbolEqual (op->operand.symOperand, tval->sym))
854 /*-----------------------------------------------------------------*/
855 /* isOperandGlobal - return 1 if operand is a global variable */
856 /*-----------------------------------------------------------------*/
858 isOperandGlobal (operand * op)
867 (op->operand.symOperand->level == 0 ||
868 IS_STATIC (op->operand.symOperand->etype) ||
869 IS_EXTERN (op->operand.symOperand->etype))
876 /*-----------------------------------------------------------------*/
877 /* isOperandVolatile - return 1 if the operand is volatile */
878 /*-----------------------------------------------------------------*/
880 isOperandVolatile (operand * op, bool chkTemp)
885 if (IS_ITEMP (op) && !chkTemp)
888 opetype = getSpec (optype = operandType (op));
890 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
893 if (IS_VOLATILE (opetype))
898 /*-----------------------------------------------------------------*/
899 /* isOperandLiteral - returns 1 if an operand contains a literal */
900 /*-----------------------------------------------------------------*/
902 isOperandLiteral (operand * op)
909 opetype = getSpec (operandType (op));
911 if (IS_LITERAL (opetype))
917 /*-----------------------------------------------------------------*/
918 /* isOperandInFarSpace - will return true if operand is in farSpace */
919 /*-----------------------------------------------------------------*/
921 isOperandInFarSpace (operand * op)
931 if (!IS_TRUE_SYMOP (op))
934 etype = SPIL_LOC (op)->etype;
940 etype = getSpec (operandType (op));
942 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
945 /*------------------------------------------------------------------*/
946 /* isOperandInDirSpace - will return true if operand is in dirSpace */
947 /*------------------------------------------------------------------*/
949 isOperandInDirSpace (operand * op)
959 if (!IS_TRUE_SYMOP (op))
962 etype = SPIL_LOC (op)->etype;
968 etype = getSpec (operandType (op));
970 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
973 /*--------------------------------------------------------------------*/
974 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
975 /*--------------------------------------------------------------------*/
977 isOperandInCodeSpace (operand * op)
987 etype = getSpec (operandType (op));
989 if (!IS_TRUE_SYMOP (op))
992 etype = SPIL_LOC (op)->etype;
998 etype = getSpec (operandType (op));
1000 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1003 /*-----------------------------------------------------------------*/
1004 /* isOperandOnStack - will return true if operand is on stack */
1005 /*-----------------------------------------------------------------*/
1007 isOperandOnStack (operand * op)
1017 etype = getSpec (operandType (op));
1018 if (IN_STACK (etype) ||
1019 OP_SYMBOL(op)->onStack ||
1020 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1026 /*-----------------------------------------------------------------*/
1027 /* isOclsExpensive - will return true if accesses to an output */
1028 /* storage class are expensive */
1029 /*-----------------------------------------------------------------*/
1031 isOclsExpensive (struct memmap *oclass)
1033 if (port->oclsExpense)
1034 return port->oclsExpense (oclass) > 0;
1036 /* In the absence of port specific guidance, assume only */
1037 /* farspace is expensive. */
1038 return IN_FARSPACE (oclass);
1041 /*-----------------------------------------------------------------*/
1042 /* operandLitValue - literal value of an operand */
1043 /*-----------------------------------------------------------------*/
1045 operandLitValue (operand * op)
1047 assert (isOperandLiteral (op));
1049 return floatFromVal (op->operand.valOperand);
1052 /*-----------------------------------------------------------------*/
1053 /* getBuiltInParms - returns parameters to a builtin functions */
1054 /*-----------------------------------------------------------------*/
1055 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1060 /* builtin functions uses only SEND for parameters */
1061 while (ic->op != CALL) {
1062 assert(ic->op == SEND && ic->builtinSEND);
1063 ic->generated = 1; /* mark the icode as generated */
1064 parms[*pcount] = IC_LEFT(ic);
1070 /* make sure this is a builtin function call */
1071 assert(IS_SYMOP(IC_LEFT(ic)));
1072 ftype = operandType(IC_LEFT(ic));
1073 assert(IFFUNC_ISBUILTIN(ftype));
1077 /*-----------------------------------------------------------------*/
1078 /* operandOperation - performs operations on operands */
1079 /*-----------------------------------------------------------------*/
1081 operandOperation (operand * left, operand * right,
1082 int op, sym_link * type)
1084 sym_link *let , *ret=NULL;
1085 operand *retval = (operand *) 0;
1087 assert (isOperandLiteral (left));
1088 let = getSpec(operandType(left));
1090 assert (isOperandLiteral (right));
1091 ret = getSpec(operandType(right));
1097 retval = operandFromValue (valCastLiteral (type,
1098 operandLitValue (left) +
1099 operandLitValue (right)));
1102 retval = operandFromValue (valCastLiteral (type,
1103 operandLitValue (left) -
1104 operandLitValue (right)));
1108 retval = operandFromValue (valCastLiteral (type,
1109 operandLitValue (left) *
1110 operandLitValue (right)));
1111 This could be all we've to do, but with gcc we've to take care about
1112 overflows. Two examples:
1113 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1114 significant bits are lost (52 in fraction, 63 bits would be
1115 necessary to keep full precision).
1116 If the resulting double value is greater than ULONG_MAX (resp.
1117 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1120 /* if it is not a specifier then we can assume that */
1121 /* it will be an unsigned long */
1122 if (IS_INT (type) ||
1125 /* long is handled here, because it can overflow with double */
1126 if (SPEC_LONG (type) ||
1128 /* signed and unsigned mul are the same, as long as the precision
1129 of the result isn't bigger than the precision of the operands. */
1130 retval = operandFromValue (valCastLiteral (type,
1131 (TYPE_UDWORD) operandLitValue (left) *
1132 (TYPE_UDWORD) operandLitValue (right)));
1133 else if (SPEC_USIGN (type)) /* unsigned int */
1135 /* unsigned int is handled here in order to detect overflow */
1136 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1137 (TYPE_UWORD) operandLitValue (right);
1139 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1140 if (ul != (TYPE_UWORD) ul)
1143 else /* signed int */
1145 /* signed int is handled here in order to detect overflow */
1146 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1147 (TYPE_WORD) operandLitValue (right);
1149 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1150 if (l != (TYPE_WORD) l)
1155 /* all others go here: */
1156 retval = operandFromValue (valCastLiteral (type,
1157 operandLitValue (left) *
1158 operandLitValue (right)));
1161 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1163 werror (E_DIVIDE_BY_ZERO);
1168 retval = operandFromValue (valCastLiteral (type,
1169 operandLitValue (left) /
1170 operandLitValue (right)));
1173 if ((TYPE_UDWORD) operandLitValue (right) == 0) {
1174 werror (E_DIVIDE_BY_ZERO);
1179 if (SPEC_USIGN(let) || SPEC_USIGN(ret))
1180 /* one of the operands is unsigned */
1181 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1182 (TYPE_UDWORD) operandLitValue (right));
1184 /* both operands are signed */
1185 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1186 (TYPE_DWORD) operandLitValue (right));
1190 /* The number of left shifts is always unsigned. Signed doesn't make
1191 sense here. Shifting by a negative number is impossible. */
1192 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1193 (TYPE_UDWORD) operandLitValue (right));
1196 /* The number of right shifts is always unsigned. Signed doesn't make
1197 sense here. Shifting by a negative number is impossible. */
1198 if (SPEC_USIGN(let))
1199 /* unsigned: logic shift right */
1200 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1201 (TYPE_UDWORD) operandLitValue (right));
1203 /* signed: arithmetic shift right */
1204 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1205 (TYPE_UDWORD) operandLitValue (right));
1208 /* this op doesn't care about signedness */
1212 l = (TYPE_UDWORD) operandLitValue (left);
1213 if (SPEC_NOUN(OP_VALUE(left)->type) == V_CHAR)
1215 else if (!SPEC_LONG (OP_VALUE(left)->type))
1217 r = (TYPE_UDWORD) operandLitValue (right);
1218 if (SPEC_NOUN(OP_VALUE(right)->type) == V_CHAR)
1220 else if (!SPEC_LONG (OP_VALUE(right)->type))
1222 retval = operandFromLit (l == r);
1226 retval = operandFromLit (operandLitValue (left) <
1227 operandLitValue (right));
1230 retval = operandFromLit (operandLitValue (left) <=
1231 operandLitValue (right));
1234 retval = operandFromLit (operandLitValue (left) !=
1235 operandLitValue (right));
1238 retval = operandFromLit (operandLitValue (left) >
1239 operandLitValue (right));
1242 retval = operandFromLit (operandLitValue (left) >=
1243 operandLitValue (right));
1246 retval = operandFromValue (valCastLiteral (type,
1247 (TYPE_UDWORD)operandLitValue(left) &
1248 (TYPE_UDWORD)operandLitValue(right)));
1251 retval = operandFromValue (valCastLiteral (type,
1252 (TYPE_UDWORD)operandLitValue(left) |
1253 (TYPE_UDWORD)operandLitValue(right)));
1256 retval = operandFromValue (valCastLiteral (type,
1257 (TYPE_UDWORD)operandLitValue(left) ^
1258 (TYPE_UDWORD)operandLitValue(right)));
1261 retval = operandFromLit (operandLitValue (left) &&
1262 operandLitValue (right));
1265 retval = operandFromLit (operandLitValue (left) ||
1266 operandLitValue (right));
1270 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1272 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1278 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1280 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1286 retval = operandFromValue (valCastLiteral (type,
1287 -1 * operandLitValue (left)));
1291 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1295 retval = operandFromLit (!operandLitValue (left));
1299 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1300 " operandOperation invalid operator ");
1308 /*-----------------------------------------------------------------*/
1309 /* isOperandEqual - compares two operand & return 1 if they r = */
1310 /*-----------------------------------------------------------------*/
1312 isOperandEqual (operand * left, operand * right)
1314 /* if the pointers are equal then they are equal */
1318 /* if either of them null then false */
1319 if (!left || !right)
1322 if (left->type != right->type)
1325 if (IS_SYMOP (left) && IS_SYMOP (right))
1326 return left->key == right->key;
1328 /* if types are the same */
1332 return isSymbolEqual (left->operand.symOperand,
1333 right->operand.symOperand);
1335 return (floatFromVal (left->operand.valOperand) ==
1336 floatFromVal (right->operand.valOperand));
1338 if (compareType (left->operand.typeOperand,
1339 right->operand.typeOperand) == 1)
1346 /*-------------------------------------------------------------------*/
1347 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1348 /*-------------------------------------------------------------------*/
1350 isiCodeEqual (iCode * left, iCode * right)
1352 /* if the same pointer */
1356 /* if either of them null */
1357 if (!left || !right)
1360 /* if operand are the same */
1361 if (left->op == right->op)
1364 /* compare all the elements depending on type */
1365 if (left->op != IFX)
1367 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1369 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1375 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1377 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1379 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1388 /*-----------------------------------------------------------------*/
1389 /* newiTempFromOp - create a temp Operand with same attributes */
1390 /*-----------------------------------------------------------------*/
1392 newiTempFromOp (operand * op)
1402 nop = newiTempOperand (operandType (op), TRUE);
1403 nop->isaddr = op->isaddr;
1404 nop->isvolatile = op->isvolatile;
1405 nop->isGlobal = op->isGlobal;
1406 nop->isLiteral = op->isLiteral;
1407 nop->usesDefs = op->usesDefs;
1408 nop->isParm = op->isParm;
1412 /*-----------------------------------------------------------------*/
1413 /* operand from operand - creates an operand holder for the type */
1414 /*-----------------------------------------------------------------*/
1416 operandFromOperand (operand * op)
1422 nop = newOperand ();
1423 nop->type = op->type;
1424 nop->isaddr = op->isaddr;
1426 nop->isvolatile = op->isvolatile;
1427 nop->isGlobal = op->isGlobal;
1428 nop->isLiteral = op->isLiteral;
1429 nop->usesDefs = op->usesDefs;
1430 nop->isParm = op->isParm;
1435 nop->operand.symOperand = op->operand.symOperand;
1438 nop->operand.valOperand = op->operand.valOperand;
1441 nop->operand.typeOperand = op->operand.typeOperand;
1448 /*-----------------------------------------------------------------*/
1449 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1450 /*-----------------------------------------------------------------*/
1452 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1454 operand *nop = operandFromOperand (op);
1456 if (nop->type == SYMBOL)
1458 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1459 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1465 /*-----------------------------------------------------------------*/
1466 /* operandFromSymbol - creates an operand from a symbol */
1467 /*-----------------------------------------------------------------*/
1469 operandFromSymbol (symbol * sym)
1474 /* if the symbol's type is a literal */
1475 /* then it is an enumerator type */
1476 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1477 return operandFromValue (valFromType (sym->etype));
1480 sym->key = ++operandKey;
1482 /* if this an implicit variable, means struct/union */
1483 /* member so just return it */
1484 if (sym->implicit || IS_FUNC (sym->type))
1488 op->operand.symOperand = sym;
1490 op->isvolatile = isOperandVolatile (op, TRUE);
1491 op->isGlobal = isOperandGlobal (op);
1495 /* under the following conditions create a
1496 register equivalent for a local symbol */
1497 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1498 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1500 (!(options.model == MODEL_FLAT24)) ) &&
1501 options.stackAuto == 0)
1504 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1505 !IS_FUNC (sym->type) && /* not a function */
1506 !sym->_isparm && /* not a parameter */
1507 sym->level && /* is a local variable */
1508 !sym->addrtaken && /* whose address has not been taken */
1509 !sym->reqv && /* does not already have a reg equivalence */
1510 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1511 !IS_STATIC (sym->etype) && /* and not declared static */
1512 !sym->islbl && /* not a label */
1513 ok && /* farspace check */
1514 !IS_BITVAR (sym->etype) /* not a bit variable */
1518 /* we will use it after all optimizations
1519 and before liveRange calculation */
1520 sym->reqv = newiTempOperand (sym->type, 0);
1521 sym->reqv->key = sym->key;
1522 OP_SYMBOL (sym->reqv)->key = sym->key;
1523 OP_SYMBOL (sym->reqv)->isreqv = 1;
1524 OP_SYMBOL (sym->reqv)->islocal = 1;
1525 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1526 SPIL_LOC (sym->reqv) = sym;
1529 if (!IS_AGGREGATE (sym->type))
1533 op->operand.symOperand = sym;
1536 op->isvolatile = isOperandVolatile (op, TRUE);
1537 op->isGlobal = isOperandGlobal (op);
1538 op->isPtr = IS_PTR (operandType (op));
1539 op->isParm = sym->_isparm;
1544 /* itemp = &[_symbol] */
1546 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1547 IC_LEFT (ic)->type = SYMBOL;
1548 IC_LEFT (ic)->operand.symOperand = sym;
1549 IC_LEFT (ic)->key = sym->key;
1550 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1551 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1552 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1555 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1556 if (IS_ARRAY (sym->type))
1558 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1559 IC_RESULT (ic)->isaddr = 0;
1562 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1566 return IC_RESULT (ic);
1569 /*-----------------------------------------------------------------*/
1570 /* operandFromValue - creates an operand from value */
1571 /*-----------------------------------------------------------------*/
1573 operandFromValue (value * val)
1577 /* if this is a symbol then do the symbol thing */
1579 return operandFromSymbol (val->sym);
1581 /* this is not a symbol */
1584 op->operand.valOperand = val;
1585 op->isLiteral = isOperandLiteral (op);
1589 /*-----------------------------------------------------------------*/
1590 /* operandFromLink - operand from typeChain */
1591 /*-----------------------------------------------------------------*/
1593 operandFromLink (sym_link * type)
1597 /* operand from sym_link */
1603 op->operand.typeOperand = copyLinkChain (type);
1607 /*-----------------------------------------------------------------*/
1608 /* operandFromLit - makes an operand from a literal value */
1609 /*-----------------------------------------------------------------*/
1611 operandFromLit (double i)
1613 return operandFromValue (valueFromLit (i));
1616 /*-----------------------------------------------------------------*/
1617 /* operandFromAst - creates an operand from an ast */
1618 /*-----------------------------------------------------------------*/
1620 operandFromAst (ast * tree,int lvl)
1626 /* depending on type do */
1630 return ast2iCode (tree,lvl+1);
1634 return operandFromValue (tree->opval.val);
1638 return operandFromLink (tree->opval.lnk);
1645 /* Just to keep the compiler happy */
1646 return (operand *) 0;
1649 /*-----------------------------------------------------------------*/
1650 /* setOperandType - sets the operand's type to the given type */
1651 /*-----------------------------------------------------------------*/
1653 setOperandType (operand * op, sym_link * type)
1655 /* depending on the type of operand */
1660 op->operand.valOperand->etype =
1661 getSpec (op->operand.valOperand->type =
1662 copyLinkChain (type));
1666 if (op->operand.symOperand->isitmp)
1667 op->operand.symOperand->etype =
1668 getSpec (op->operand.symOperand->type =
1669 copyLinkChain (type));
1671 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1672 "attempt to modify type of source");
1676 op->operand.typeOperand = copyLinkChain (type);
1681 /*-----------------------------------------------------------------*/
1682 /* Get size in byte of ptr need to access an array */
1683 /*-----------------------------------------------------------------*/
1685 getArraySizePtr (operand * op)
1687 sym_link *ltype = operandType(op);
1691 int size = getSize(ltype);
1692 return(IS_GENPTR(ltype)?(size-1):size);
1697 sym_link *letype = getSpec(ltype);
1698 switch (PTR_TYPE (SPEC_OCLS (letype)))
1710 return (GPTRSIZE-1);
1719 /*-----------------------------------------------------------------*/
1720 /* perform "usual unary conversions" */
1721 /*-----------------------------------------------------------------*/
1723 usualUnaryConversions (operand * op)
1725 if (IS_INTEGRAL (operandType (op)))
1727 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1730 return geniCodeCast (INTTYPE, op, TRUE);
1736 /*-----------------------------------------------------------------*/
1737 /* perform "usual binary conversions" */
1738 /*-----------------------------------------------------------------*/
1740 usualBinaryConversions (operand ** op1, operand ** op2)
1743 sym_link *rtype = operandType (*op2);
1744 sym_link *ltype = operandType (*op1);
1746 ctype = computeType (ltype, rtype);
1748 *op1 = geniCodeCast (ctype, *op1, TRUE);
1749 *op2 = geniCodeCast (ctype, *op2, TRUE);
1754 /*-----------------------------------------------------------------*/
1755 /* geniCodeValueAtAddress - generate intermeditate code for value */
1757 /*-----------------------------------------------------------------*/
1759 geniCodeRValue (operand * op, bool force)
1762 sym_link *type = operandType (op);
1763 sym_link *etype = getSpec (type);
1765 /* if this is an array & already */
1766 /* an address then return this */
1767 if (IS_AGGREGATE (type) ||
1768 (IS_PTR (type) && !force && !op->isaddr))
1769 return operandFromOperand (op);
1771 /* if this is not an address then must be */
1772 /* rvalue already so return this one */
1776 /* if this is not a temp symbol then */
1777 if (!IS_ITEMP (op) &&
1779 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1781 op = operandFromOperand (op);
1786 if (IS_SPEC (type) &&
1787 IS_TRUE_SYMOP (op) &&
1788 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1789 (options.model == MODEL_FLAT24) ))
1791 op = operandFromOperand (op);
1796 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1797 if (IS_PTR (type) && op->isaddr && force)
1800 type = copyLinkChain (type);
1802 IC_RESULT (ic) = newiTempOperand (type, 1);
1803 IC_RESULT (ic)->isaddr = 0;
1805 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1809 return IC_RESULT (ic);
1812 /*-----------------------------------------------------------------*/
1813 /* geniCodeCast - changes the value from one type to another */
1814 /*-----------------------------------------------------------------*/
1816 geniCodeCast (sym_link * type, operand * op, bool implicit)
1820 sym_link *opetype = getSpec (optype = operandType (op));
1824 /* one of them has size zero then error */
1825 if (IS_VOID (optype))
1827 werror (E_CAST_ZERO);
1831 /* if the operand is already the desired type then do nothing */
1832 if (compareType (type, optype) == 1)
1835 /* if this is a literal then just change the type & return */
1836 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1837 return operandFromValue (valCastLiteral (type,
1838 operandLitValue (op)));
1840 /* if casting to/from pointers, do some checking */
1841 if (IS_PTR(type)) { // to a pointer
1842 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1843 if (IS_INTEGRAL(optype)) {
1844 // maybe this is NULL, than it's ok.
1845 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1846 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1847 // no way to set the storage
1848 if (IS_LITERAL(optype)) {
1849 werror(E_LITERAL_GENERIC);
1852 werror(E_NONPTR2_GENPTR);
1855 } else if (implicit) {
1856 werror(W_INTEGRAL2PTR_NOCAST);
1861 // shouldn't do that with float, array or structure unless to void
1862 if (!IS_VOID(getSpec(type)) &&
1863 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1864 werror(E_INCOMPAT_TYPES);
1868 } else { // from a pointer to a pointer
1869 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1870 // if not a pointer to a function
1871 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1872 if (implicit) { // if not to generic, they have to match
1873 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1874 werror(E_INCOMPAT_PTYPES);
1881 } else { // to a non pointer
1882 if (IS_PTR(optype)) { // from a pointer
1883 if (implicit) { // sneaky
1884 if (IS_INTEGRAL(type)) {
1885 werror(W_PTR2INTEGRAL_NOCAST);
1887 } else { // shouldn't do that with float, array or structure
1888 werror(E_INCOMPAT_TYPES);
1895 printFromToType (optype, type);
1898 /* if they are the same size create an assignment */
1899 if (getSize (type) == getSize (optype) &&
1900 !IS_BITFIELD (type) &&
1902 !IS_FLOAT (optype) &&
1903 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1904 (!IS_SPEC (type) && !IS_SPEC (optype))))
1907 ic = newiCode ('=', NULL, op);
1908 IC_RESULT (ic) = newiTempOperand (type, 0);
1909 SPIL_LOC (IC_RESULT (ic)) =
1910 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1911 IC_RESULT (ic)->isaddr = 0;
1915 ic = newiCode (CAST, operandFromLink (type),
1916 geniCodeRValue (op, FALSE));
1918 IC_RESULT (ic) = newiTempOperand (type, 0);
1921 /* preserve the storage class & output class */
1922 /* of the original variable */
1923 restype = getSpec (operandType (IC_RESULT (ic)));
1924 if (!IS_LITERAL(opetype))
1925 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1926 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1929 return IC_RESULT (ic);
1932 /*-----------------------------------------------------------------*/
1933 /* geniCodeLabel - will create a Label */
1934 /*-----------------------------------------------------------------*/
1936 geniCodeLabel (symbol * label)
1940 ic = newiCodeLabelGoto (LABEL, label);
1944 /*-----------------------------------------------------------------*/
1945 /* geniCodeGoto - will create a Goto */
1946 /*-----------------------------------------------------------------*/
1948 geniCodeGoto (symbol * label)
1952 ic = newiCodeLabelGoto (GOTO, label);
1956 /*-----------------------------------------------------------------*/
1957 /* geniCodeMultiply - gen intermediate code for multiplication */
1958 /*-----------------------------------------------------------------*/
1960 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1967 /* if they are both literal then we know the result */
1968 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1969 return operandFromValue (valMult (left->operand.valOperand,
1970 right->operand.valOperand));
1972 if (IS_LITERAL(retype)) {
1973 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1976 resType = usualBinaryConversions (&left, &right);
1978 rtype = operandType (right);
1979 retype = getSpec (rtype);
1980 ltype = operandType (left);
1981 letype = getSpec (ltype);
1985 SPEC_NOUN(getSpec(resType))=V_INT;
1988 /* if the right is a literal & power of 2 */
1989 /* then make it a left shift */
1990 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1991 efficient in most cases than 2 bytes result = 2 bytes << literal
1992 if port has 1 byte muldiv */
1993 if (p2 && !IS_FLOAT (letype) &&
1994 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1995 (port->support.muldiv == 1)))
1997 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1999 /* LEFT_OP need same size for left and result, */
2000 left = geniCodeCast (resType, left, TRUE);
2001 ltype = operandType (left);
2003 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2007 ic = newiCode ('*', left, right); /* normal multiplication */
2008 /* if the size left or right > 1 then support routine */
2009 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2013 IC_RESULT (ic) = newiTempOperand (resType, 1);
2016 return IC_RESULT (ic);
2019 /*-----------------------------------------------------------------*/
2020 /* geniCodeDivision - gen intermediate code for division */
2021 /*-----------------------------------------------------------------*/
2023 geniCodeDivision (operand * left, operand * right)
2028 sym_link *rtype = operandType (right);
2029 sym_link *retype = getSpec (rtype);
2030 sym_link *ltype = operandType (left);
2031 sym_link *letype = getSpec (ltype);
2033 resType = usualBinaryConversions (&left, &right);
2035 /* if the right is a literal & power of 2
2036 and left is unsigned then make it a
2038 if (IS_LITERAL (retype) &&
2039 !IS_FLOAT (letype) &&
2040 SPEC_USIGN(letype) &&
2041 (p2 = powof2 ((unsigned long)
2042 floatFromVal (right->operand.valOperand)))) {
2043 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2047 ic = newiCode ('/', left, right); /* normal division */
2048 /* if the size left or right > 1 then support routine */
2049 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2052 IC_RESULT (ic) = newiTempOperand (resType, 0);
2055 return IC_RESULT (ic);
2057 /*-----------------------------------------------------------------*/
2058 /* geniCodeModulus - gen intermediate code for modulus */
2059 /*-----------------------------------------------------------------*/
2061 geniCodeModulus (operand * left, operand * right)
2067 /* if they are both literal then we know the result */
2068 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2069 return operandFromValue (valMod (left->operand.valOperand,
2070 right->operand.valOperand));
2072 resType = usualBinaryConversions (&left, &right);
2074 /* now they are the same size */
2075 ic = newiCode ('%', left, right);
2077 /* if the size left or right > 1 then support routine */
2078 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2080 IC_RESULT (ic) = newiTempOperand (resType, 0);
2083 return IC_RESULT (ic);
2086 /*-----------------------------------------------------------------*/
2087 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2088 /*-----------------------------------------------------------------*/
2090 geniCodePtrPtrSubtract (operand * left, operand * right)
2096 /* if they are both literals then */
2097 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2099 result = operandFromValue (valMinus (left->operand.valOperand,
2100 right->operand.valOperand));
2104 ic = newiCode ('-', left, right);
2106 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2110 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2114 // should we really do this? is this ANSI?
2115 return geniCodeDivision (result,
2116 operandFromLit (getSize (ltype->next)));
2119 /*-----------------------------------------------------------------*/
2120 /* geniCodeSubtract - generates code for subtraction */
2121 /*-----------------------------------------------------------------*/
2123 geniCodeSubtract (operand * left, operand * right)
2130 /* if they both pointers then */
2131 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2132 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2133 return geniCodePtrPtrSubtract (left, right);
2135 /* if they are both literal then we know the result */
2136 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2137 && left->isLiteral && right->isLiteral)
2138 return operandFromValue (valMinus (left->operand.valOperand,
2139 right->operand.valOperand));
2141 /* if left is an array or pointer */
2142 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2144 isarray = left->isaddr;
2145 right = geniCodeMultiply (right,
2146 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2147 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2150 { /* make them the same size */
2151 resType = usualBinaryConversions (&left, &right);
2154 ic = newiCode ('-', left, right);
2156 IC_RESULT (ic) = newiTempOperand (resType, 1);
2157 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2159 /* if left or right is a float */
2160 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2164 return IC_RESULT (ic);
2167 /*-----------------------------------------------------------------*/
2168 /* geniCodeAdd - generates iCode for addition */
2169 /*-----------------------------------------------------------------*/
2171 geniCodeAdd (operand * left, operand * right, int lvl)
2179 /* if the right side is LITERAL zero */
2180 /* return the left side */
2181 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2184 /* if left is literal zero return right */
2185 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2188 /* if left is a pointer then size */
2189 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2191 isarray = left->isaddr;
2192 // there is no need to multiply with 1
2193 if (getSize(ltype->next)!=1) {
2194 size = operandFromLit (getSize (ltype->next));
2195 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2197 resType = copyLinkChain (ltype);
2200 { // make them the same size
2201 resType = usualBinaryConversions (&left, &right);
2204 /* if they are both literals then we know */
2205 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2206 && left->isLiteral && right->isLiteral)
2207 return operandFromValue (valPlus (valFromType (ltype),
2208 valFromType (rtype)));
2210 ic = newiCode ('+', left, right);
2212 IC_RESULT (ic) = newiTempOperand (resType, 1);
2213 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2215 /* if left or right is a float then support
2217 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2222 return IC_RESULT (ic);
2226 /*-----------------------------------------------------------------*/
2227 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2228 /*-----------------------------------------------------------------*/
2230 aggrToPtr (sym_link * type, bool force)
2235 if (IS_PTR (type) && !force)
2238 etype = getSpec (type);
2239 ptype = newLink (DECLARATOR);
2243 /* set the pointer depending on the storage class */
2244 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2248 /*-----------------------------------------------------------------*/
2249 /* geniCodeArray2Ptr - array to pointer */
2250 /*-----------------------------------------------------------------*/
2252 geniCodeArray2Ptr (operand * op)
2254 sym_link *optype = operandType (op);
2255 sym_link *opetype = getSpec (optype);
2257 /* set the pointer depending on the storage class */
2258 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2265 /*-----------------------------------------------------------------*/
2266 /* geniCodeArray - array access */
2267 /*-----------------------------------------------------------------*/
2269 geniCodeArray (operand * left, operand * right,int lvl)
2272 sym_link *ltype = operandType (left);
2276 if (IS_PTR (ltype->next) && left->isaddr)
2278 left = geniCodeRValue (left, FALSE);
2281 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2284 right = geniCodeMultiply (right,
2285 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2287 /* we can check for limits here */
2288 if (isOperandLiteral (right) &&
2291 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2293 werror (E_ARRAY_BOUND);
2294 right = operandFromLit (0);
2297 ic = newiCode ('+', left, right);
2299 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2300 !IS_AGGREGATE (ltype->next) &&
2301 !IS_PTR (ltype->next))
2302 ? ltype : ltype->next), 0);
2304 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2307 return IC_RESULT (ic);
2310 /*-----------------------------------------------------------------*/
2311 /* geniCodeStruct - generates intermediate code for structres */
2312 /*-----------------------------------------------------------------*/
2314 geniCodeStruct (operand * left, operand * right, bool islval)
2317 sym_link *type = operandType (left);
2318 sym_link *etype = getSpec (type);
2320 symbol *element = getStructElement (SPEC_STRUCT (etype),
2321 right->operand.symOperand);
2323 wassert(IS_SYMOP(right));
2325 /* add the offset */
2326 ic = newiCode ('+', left, operandFromLit (element->offset));
2328 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2330 /* preserve the storage & output class of the struct */
2331 /* as well as the volatile attribute */
2332 retype = getSpec (operandType (IC_RESULT (ic)));
2333 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2334 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2335 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2336 SPEC_CONST (retype) |= SPEC_CONST (etype);
2338 if (IS_PTR (element->type))
2339 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2341 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2344 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2347 /*-----------------------------------------------------------------*/
2348 /* geniCodePostInc - generate int code for Post increment */
2349 /*-----------------------------------------------------------------*/
2351 geniCodePostInc (operand * op)
2355 sym_link *optype = operandType (op);
2357 operand *rv = (IS_ITEMP (op) ?
2358 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2360 sym_link *rvtype = operandType (rv);
2363 /* if this is not an address we have trouble */
2366 werror (E_LVALUE_REQUIRED, "++");
2370 rOp = newiTempOperand (rvtype, 0);
2371 OP_SYMBOL(rOp)->noSpilLoc = 1;
2374 OP_SYMBOL(rv)->noSpilLoc = 1;
2376 geniCodeAssign (rOp, rv, 0);
2378 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2379 if (IS_FLOAT (rvtype))
2380 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2382 ic = newiCode ('+', rv, operandFromLit (size));
2384 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2387 geniCodeAssign (op, result, 0);
2393 /*-----------------------------------------------------------------*/
2394 /* geniCodePreInc - generate code for preIncrement */
2395 /*-----------------------------------------------------------------*/
2397 geniCodePreInc (operand * op, bool lvalue)
2400 sym_link *optype = operandType (op);
2401 operand *rop = (IS_ITEMP (op) ?
2402 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2404 sym_link *roptype = operandType (rop);
2410 werror (E_LVALUE_REQUIRED, "++");
2415 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2416 if (IS_FLOAT (roptype))
2417 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2419 ic = newiCode ('+', rop, operandFromLit (size));
2420 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2423 (void) geniCodeAssign (op, result, 0);
2424 if (lvalue || IS_TRUE_SYMOP (op))
2430 /*-----------------------------------------------------------------*/
2431 /* geniCodePostDec - generates code for Post decrement */
2432 /*-----------------------------------------------------------------*/
2434 geniCodePostDec (operand * op)
2438 sym_link *optype = operandType (op);
2440 operand *rv = (IS_ITEMP (op) ?
2441 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2443 sym_link *rvtype = operandType (rv);
2446 /* if this is not an address we have trouble */
2449 werror (E_LVALUE_REQUIRED, "--");
2453 rOp = newiTempOperand (rvtype, 0);
2454 OP_SYMBOL(rOp)->noSpilLoc = 1;
2457 OP_SYMBOL(rv)->noSpilLoc = 1;
2459 geniCodeAssign (rOp, rv, 0);
2461 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2462 if (IS_FLOAT (rvtype))
2463 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2465 ic = newiCode ('-', rv, operandFromLit (size));
2467 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2470 geniCodeAssign (op, result, 0);
2476 /*-----------------------------------------------------------------*/
2477 /* geniCodePreDec - generate code for pre decrement */
2478 /*-----------------------------------------------------------------*/
2480 geniCodePreDec (operand * op, bool lvalue)
2483 sym_link *optype = operandType (op);
2484 operand *rop = (IS_ITEMP (op) ?
2485 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2487 sym_link *roptype = operandType (rop);
2493 werror (E_LVALUE_REQUIRED, "--");
2498 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2499 if (IS_FLOAT (roptype))
2500 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2502 ic = newiCode ('-', rop, operandFromLit (size));
2503 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2506 (void) geniCodeAssign (op, result, 0);
2507 if (lvalue || IS_TRUE_SYMOP (op))
2514 /*-----------------------------------------------------------------*/
2515 /* geniCodeBitwise - gen int code for bitWise operators */
2516 /*-----------------------------------------------------------------*/
2518 geniCodeBitwise (operand * left, operand * right,
2519 int oper, sym_link * resType)
2523 left = geniCodeCast (resType, left, TRUE);
2524 right = geniCodeCast (resType, right, TRUE);
2526 ic = newiCode (oper, left, right);
2527 IC_RESULT (ic) = newiTempOperand (resType, 0);
2530 return IC_RESULT (ic);
2533 /*-----------------------------------------------------------------*/
2534 /* geniCodeAddressOf - gens icode for '&' address of operator */
2535 /*-----------------------------------------------------------------*/
2537 geniCodeAddressOf (operand * op)
2541 sym_link *optype = operandType (op);
2542 sym_link *opetype = getSpec (optype);
2544 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2546 op = operandFromOperand (op);
2551 /* lvalue check already done in decorateType */
2552 /* this must be a lvalue */
2553 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2554 /* werror (E_LVALUE_REQUIRED,"&"); */
2558 p = newLink (DECLARATOR);
2560 /* set the pointer depending on the storage class */
2561 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2563 p->next = copyLinkChain (optype);
2565 /* if already a temp */
2568 setOperandType (op, p);
2573 /* other wise make this of the type coming in */
2574 ic = newiCode (ADDRESS_OF, op, NULL);
2575 IC_RESULT (ic) = newiTempOperand (p, 1);
2576 IC_RESULT (ic)->isaddr = 0;
2578 return IC_RESULT (ic);
2580 /*-----------------------------------------------------------------*/
2581 /* setOClass - sets the output class depending on the pointer type */
2582 /*-----------------------------------------------------------------*/
2584 setOClass (sym_link * ptr, sym_link * spec)
2586 switch (DCL_TYPE (ptr))
2589 SPEC_OCLS (spec) = data;
2593 SPEC_OCLS (spec) = generic;
2597 SPEC_OCLS (spec) = xdata;
2601 SPEC_OCLS (spec) = code;
2605 SPEC_OCLS (spec) = idata;
2609 SPEC_OCLS (spec) = xstack;
2613 SPEC_OCLS (spec) = eeprom;
2622 /*-----------------------------------------------------------------*/
2623 /* geniCodeDerefPtr - dereference pointer with '*' */
2624 /*-----------------------------------------------------------------*/
2626 geniCodeDerefPtr (operand * op,int lvl)
2628 sym_link *rtype, *retype;
2629 sym_link *optype = operandType (op);
2631 // if this is an array then array access
2632 if (IS_ARRAY (optype)) {
2633 // don't worry, this will be optimized out later
2634 return geniCodeArray (op, operandFromLit (0), lvl);
2637 // just in case someone screws up
2638 wassert (IS_PTR (optype));
2640 if (IS_TRUE_SYMOP (op))
2643 op = geniCodeRValue (op, TRUE);
2646 /* now get rid of the pointer part */
2647 if (isLvaluereq(lvl) && IS_ITEMP (op))
2649 retype = getSpec (rtype = copyLinkChain (optype));
2653 retype = getSpec (rtype = copyLinkChain (optype->next));
2654 /* outputclass needs 2b updated */
2655 setOClass (optype, retype);
2658 op->isGptr = IS_GENPTR (optype);
2660 op->isaddr = (IS_PTR (rtype) ||
2661 IS_STRUCT (rtype) ||
2666 if (!isLvaluereq(lvl))
2667 op = geniCodeRValue (op, TRUE);
2669 setOperandType (op, rtype);
2674 /*-----------------------------------------------------------------*/
2675 /* geniCodeUnaryMinus - does a unary minus of the operand */
2676 /*-----------------------------------------------------------------*/
2678 geniCodeUnaryMinus (operand * op)
2681 sym_link *optype = operandType (op);
2683 if (IS_LITERAL (optype))
2684 return operandFromLit (-floatFromVal (op->operand.valOperand));
2686 ic = newiCode (UNARYMINUS, op, NULL);
2687 IC_RESULT (ic) = newiTempOperand (optype, 0);
2689 return IC_RESULT (ic);
2692 /*-----------------------------------------------------------------*/
2693 /* geniCodeLeftShift - gen i code for left shift */
2694 /*-----------------------------------------------------------------*/
2696 geniCodeLeftShift (operand * left, operand * right)
2700 ic = newiCode (LEFT_OP, left, right);
2701 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2703 return IC_RESULT (ic);
2706 /*-----------------------------------------------------------------*/
2707 /* geniCodeRightShift - gen i code for right shift */
2708 /*-----------------------------------------------------------------*/
2710 geniCodeRightShift (operand * left, operand * right)
2714 ic = newiCode (RIGHT_OP, left, right);
2715 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2717 return IC_RESULT (ic);
2720 /*-----------------------------------------------------------------*/
2721 /* geniCodeLogic- logic code */
2722 /*-----------------------------------------------------------------*/
2724 geniCodeLogic (operand * left, operand * right, int op)
2728 sym_link *rtype = operandType (right);
2729 sym_link *ltype = operandType (left);
2731 /* left is integral type and right is literal then
2732 check if the literal value is within bounds */
2733 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2735 checkConstantRange(ltype,
2736 OP_VALUE(right), "compare operation", 1);
2739 /* if one operand is a pointer and the other is a literal generic void pointer,
2740 change the type of the literal generic void pointer to match the other pointer */
2741 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2742 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2744 /* find left's definition */
2745 ic = (iCode *) setFirstItem (iCodeChain);
2748 if (((ic->op == CAST) || (ic->op == '='))
2749 && isOperandEqual(left, IC_RESULT (ic)))
2752 ic = setNextItem (iCodeChain);
2754 /* if casting literal to generic pointer, then cast to rtype instead */
2755 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2757 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2758 ltype = operandType(left);
2761 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2762 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2764 /* find right's definition */
2765 ic = (iCode *) setFirstItem (iCodeChain);
2768 if (((ic->op == CAST) || (ic->op == '='))
2769 && isOperandEqual(right, IC_RESULT (ic)))
2772 ic = setNextItem (iCodeChain);
2774 /* if casting literal to generic pointer, then cast to rtype instead */
2775 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2777 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2778 rtype = operandType(right);
2782 ctype = usualBinaryConversions (&left, &right);
2784 ic = newiCode (op, left, right);
2785 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2787 /* if comparing float
2788 and not a '==' || '!=' || '&&' || '||' (these
2790 if (IS_FLOAT(ctype) &&
2798 return IC_RESULT (ic);
2801 /*-----------------------------------------------------------------*/
2802 /* geniCodeUnary - for a a generic unary operation */
2803 /*-----------------------------------------------------------------*/
2805 geniCodeUnary (operand * op, int oper)
2807 iCode *ic = newiCode (oper, op, NULL);
2809 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2811 return IC_RESULT (ic);
2814 /*-----------------------------------------------------------------*/
2815 /* geniCodeConditional - geniCode for '?' ':' operation */
2816 /*-----------------------------------------------------------------*/
2818 geniCodeConditional (ast * tree,int lvl)
2821 symbol *falseLabel = newiTempLabel (NULL);
2822 symbol *exitLabel = newiTempLabel (NULL);
2823 operand *cond = ast2iCode (tree->left,lvl+1);
2824 operand *true, *false, *result;
2826 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2830 true = ast2iCode (tree->right->left,lvl+1);
2832 /* move the value to a new Operand */
2833 result = newiTempOperand (tree->right->ftype, 0);
2834 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2836 /* generate an unconditional goto */
2837 geniCodeGoto (exitLabel);
2839 /* now for the right side */
2840 geniCodeLabel (falseLabel);
2842 false = ast2iCode (tree->right->right,lvl+1);
2843 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2845 /* create the exit label */
2846 geniCodeLabel (exitLabel);
2851 /*-----------------------------------------------------------------*/
2852 /* geniCodeAssign - generate code for assignment */
2853 /*-----------------------------------------------------------------*/
2855 geniCodeAssign (operand * left, operand * right, int nosupdate)
2858 sym_link *ltype = operandType (left);
2859 sym_link *rtype = operandType (right);
2861 if (!left->isaddr && !IS_ITEMP (left))
2863 werror (E_LVALUE_REQUIRED, "assignment");
2867 /* left is integral type and right is literal then
2868 check if the literal value is within bounds */
2869 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2871 checkConstantRange(ltype,
2872 OP_VALUE(right), "= operation", 0);
2875 /* if the left & right type don't exactly match */
2876 /* if pointer set then make sure the check is
2877 done with the type & not the pointer */
2878 /* then cast rights type to left */
2880 /* first check the type for pointer assignement */
2881 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2882 compareType (ltype, rtype) <= 0)
2884 if (compareType (ltype->next, rtype) < 0)
2885 right = geniCodeCast (ltype->next, right, TRUE);
2887 else if (compareType (ltype, rtype) < 0)
2888 right = geniCodeCast (ltype, right, TRUE);
2890 /* If left is a true symbol & ! volatile
2891 create an assignment to temporary for
2892 the right & then assign this temporary
2893 to the symbol. This is SSA (static single
2894 assignment). Isn't it simple and folks have
2895 published mountains of paper on it */
2896 if (IS_TRUE_SYMOP (left) &&
2897 !isOperandVolatile (left, FALSE) &&
2898 isOperandGlobal (left))
2902 if (IS_TRUE_SYMOP (right))
2903 sym = OP_SYMBOL (right);
2904 ic = newiCode ('=', NULL, right);
2905 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2906 SPIL_LOC (right) = sym;
2910 ic = newiCode ('=', NULL, right);
2911 IC_RESULT (ic) = left;
2914 /* if left isgptr flag is set then support
2915 routine will be required */
2919 ic->nosupdate = nosupdate;
2923 /*-----------------------------------------------------------------*/
2924 /* geniCodeDummyRead - generate code for dummy read */
2925 /*-----------------------------------------------------------------*/
2927 geniCodeDummyRead (operand * op)
2930 sym_link *type = operandType (op);
2932 if (!IS_VOLATILE(type))
2935 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2941 /*-----------------------------------------------------------------*/
2942 /* geniCodeSEParms - generate code for side effecting fcalls */
2943 /*-----------------------------------------------------------------*/
2945 geniCodeSEParms (ast * parms,int lvl)
2950 if (parms->type == EX_OP && parms->opval.op == PARAM)
2952 geniCodeSEParms (parms->left,lvl);
2953 geniCodeSEParms (parms->right,lvl);
2957 /* hack don't like this but too lazy to think of
2959 if (IS_ADDRESS_OF_OP (parms))
2960 parms->left->lvalue = 1;
2962 if (IS_CAST_OP (parms) &&
2963 IS_PTR (parms->ftype) &&
2964 IS_ADDRESS_OF_OP (parms->right))
2965 parms->right->left->lvalue = 1;
2967 parms->opval.oprnd =
2968 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2970 parms->type = EX_OPERAND;
2971 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2972 SPEC_ARGREG(parms->ftype);
2975 /*-----------------------------------------------------------------*/
2976 /* geniCodeParms - generates parameters */
2977 /*-----------------------------------------------------------------*/
2979 geniCodeParms (ast * parms, value *argVals, int *stack,
2980 sym_link * fetype, symbol * func,int lvl)
2988 if (argVals==NULL) {
2990 argVals=FUNC_ARGS(func->type);
2993 /* if this is a param node then do the left & right */
2994 if (parms->type == EX_OP && parms->opval.op == PARAM)
2996 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2997 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
3001 /* get the parameter value */
3002 if (parms->type == EX_OPERAND)
3003 pval = parms->opval.oprnd;
3006 /* maybe this else should go away ?? */
3007 /* hack don't like this but too lazy to think of
3009 if (IS_ADDRESS_OF_OP (parms))
3010 parms->left->lvalue = 1;
3012 if (IS_CAST_OP (parms) &&
3013 IS_PTR (parms->ftype) &&
3014 IS_ADDRESS_OF_OP (parms->right))
3015 parms->right->left->lvalue = 1;
3017 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3020 /* if register parm then make it a send */
3021 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3022 IFFUNC_ISBUILTIN(func->type))
3024 ic = newiCode (SEND, pval, NULL);
3025 ic->argreg = SPEC_ARGREG(parms->etype);
3026 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3031 /* now decide whether to push or assign */
3032 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3036 operand *top = operandFromSymbol (argVals->sym);
3037 /* clear useDef and other bitVectors */
3038 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3039 geniCodeAssign (top, pval, 1);
3043 sym_link *p = operandType (pval);
3045 ic = newiCode (IPUSH, pval, NULL);
3047 /* update the stack adjustment */
3048 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3053 argVals=argVals->next;
3057 /*-----------------------------------------------------------------*/
3058 /* geniCodeCall - generates temp code for calling */
3059 /*-----------------------------------------------------------------*/
3061 geniCodeCall (operand * left, ast * parms,int lvl)
3065 sym_link *type, *etype;
3068 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3069 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3070 werror (E_FUNCTION_EXPECTED);
3071 return operandFromValue(valueFromLit(0));
3074 /* take care of parameters with side-effecting
3075 function calls in them, this is required to take care
3076 of overlaying function parameters */
3077 geniCodeSEParms (parms,lvl);
3079 /* first the parameters */
3080 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3082 /* now call : if symbol then pcall */
3083 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3084 ic = newiCode (PCALL, left, NULL);
3086 ic = newiCode (CALL, left, NULL);
3089 type = copyLinkChain (operandType (left)->next);
3090 etype = getSpec (type);
3091 SPEC_EXTR (etype) = 0;
3092 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3096 /* stack adjustment after call */
3097 ic->parmBytes = stack;
3102 /*-----------------------------------------------------------------*/
3103 /* geniCodeReceive - generate intermediate code for "receive" */
3104 /*-----------------------------------------------------------------*/
3106 geniCodeReceive (value * args)
3108 /* for all arguments that are passed in registers */
3112 if (IS_REGPARM (args->etype))
3114 operand *opr = operandFromValue (args);
3116 symbol *sym = OP_SYMBOL (opr);
3119 /* we will use it after all optimizations
3120 and before liveRange calculation */
3121 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3124 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3125 options.stackAuto == 0 &&
3126 (!(options.model == MODEL_FLAT24)) )
3131 opl = newiTempOperand (args->type, 0);
3133 sym->reqv->key = sym->key;
3134 OP_SYMBOL (sym->reqv)->key = sym->key;
3135 OP_SYMBOL (sym->reqv)->isreqv = 1;
3136 OP_SYMBOL (sym->reqv)->islocal = 0;
3137 SPIL_LOC (sym->reqv) = sym;
3141 ic = newiCode (RECEIVE, NULL, NULL);
3142 ic->argreg = SPEC_ARGREG(args->etype);
3144 currFunc->recvSize = getSize (sym->type);
3147 IC_RESULT (ic) = opr;
3155 /*-----------------------------------------------------------------*/
3156 /* geniCodeFunctionBody - create the function body */
3157 /*-----------------------------------------------------------------*/
3159 geniCodeFunctionBody (ast * tree,int lvl)
3166 /* reset the auto generation */
3172 func = ast2iCode (tree->left,lvl+1);
3173 fetype = getSpec (operandType (func));
3175 savelineno = lineno;
3176 lineno = OP_SYMBOL (func)->lineDef;
3177 /* create an entry label */
3178 geniCodeLabel (entryLabel);
3179 lineno = savelineno;
3181 /* create a proc icode */
3182 ic = newiCode (FUNCTION, func, NULL);
3183 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3187 /* for all parameters that are passed
3188 on registers add a "receive" */
3189 geniCodeReceive (tree->values.args);
3191 /* generate code for the body */
3192 ast2iCode (tree->right,lvl+1);
3194 /* create a label for return */
3195 geniCodeLabel (returnLabel);
3197 /* now generate the end proc */
3198 ic = newiCode (ENDFUNCTION, func, NULL);
3203 /*-----------------------------------------------------------------*/
3204 /* geniCodeReturn - gen icode for 'return' statement */
3205 /*-----------------------------------------------------------------*/
3207 geniCodeReturn (operand * op)
3211 /* if the operand is present force an rvalue */
3213 op = geniCodeRValue (op, FALSE);
3215 ic = newiCode (RETURN, op, NULL);
3219 /*-----------------------------------------------------------------*/
3220 /* geniCodeIfx - generates code for extended if statement */
3221 /*-----------------------------------------------------------------*/
3223 geniCodeIfx (ast * tree,int lvl)
3226 operand *condition = ast2iCode (tree->left,lvl+1);
3229 /* if condition is null then exit */
3233 condition = geniCodeRValue (condition, FALSE);
3235 cetype = getSpec (operandType (condition));
3236 /* if the condition is a literal */
3237 if (IS_LITERAL (cetype))
3239 if (floatFromVal (condition->operand.valOperand))
3241 if (tree->trueLabel)
3242 geniCodeGoto (tree->trueLabel);
3248 if (tree->falseLabel)
3249 geniCodeGoto (tree->falseLabel);
3256 if (tree->trueLabel)
3258 ic = newiCodeCondition (condition,
3263 if (tree->falseLabel)
3264 geniCodeGoto (tree->falseLabel);
3268 ic = newiCodeCondition (condition,
3275 ast2iCode (tree->right,lvl+1);
3278 /*-----------------------------------------------------------------*/
3279 /* geniCodeJumpTable - tries to create a jump table for switch */
3280 /*-----------------------------------------------------------------*/
3282 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3284 int min = 0, max = 0, t, cnt = 0;
3290 int needRangeCheck = !optimize.noJTabBoundary
3291 || tree->values.switchVals.swDefault;
3293 if (!tree || !caseVals)
3296 /* the criteria for creating a jump table is */
3297 /* all integer numbers between the maximum & minimum must */
3298 /* be present , the maximum value should not exceed 255 */
3299 min = max = (int) floatFromVal (vch = caseVals);
3300 SNPRINTF (buffer, sizeof(buffer),
3302 tree->values.switchVals.swNum,
3304 addSet (&labels, newiTempLabel (buffer));
3306 /* if there is only one case value then no need */
3307 if (!(vch = vch->next))
3312 if (((t = (int) floatFromVal (vch)) - max) != 1)
3314 SNPRINTF (buffer, sizeof(buffer),
3316 tree->values.switchVals.swNum,
3318 addSet (&labels, newiTempLabel (buffer));
3324 /* if the number of case statements <= 2 then */
3325 /* it is not economical to create the jump table */
3326 /* since two compares are needed for boundary conditions */
3327 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3330 if (tree->values.switchVals.swDefault)
3332 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3336 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3340 falseLabel = newiTempLabel (buffer);
3342 /* so we can create a jumptable */
3343 /* first we rule out the boundary conditions */
3344 /* if only optimization says so */
3347 sym_link *cetype = getSpec (operandType (cond));
3348 /* no need to check the lower bound if
3349 the condition is unsigned & minimum value is zero */
3350 if (!(min == 0 && SPEC_USIGN (cetype)))
3352 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3353 ic = newiCodeCondition (boundary, falseLabel, NULL);
3357 /* now for upper bounds */
3358 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3359 ic = newiCodeCondition (boundary, falseLabel, NULL);
3363 /* if the min is not zero then we no make it zero */
3366 cond = geniCodeSubtract (cond, operandFromLit (min));
3367 if (!IS_LITERAL(getSpec(operandType(cond))))
3368 setOperandType (cond, UCHARTYPE);
3371 /* now create the jumptable */
3372 ic = newiCode (JUMPTABLE, NULL, NULL);
3373 IC_JTCOND (ic) = cond;
3374 IC_JTLABELS (ic) = labels;
3379 /*-----------------------------------------------------------------*/
3380 /* geniCodeSwitch - changes a switch to a if statement */
3381 /*-----------------------------------------------------------------*/
3383 geniCodeSwitch (ast * tree,int lvl)
3386 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3387 value *caseVals = tree->values.switchVals.swVals;
3388 symbol *trueLabel, *falseLabel;
3390 /* If the condition is a literal, then just jump to the */
3391 /* appropriate case label. */
3392 if (IS_LITERAL(getSpec(operandType(cond))))
3394 int switchVal, caseVal;
3396 switchVal = (int) floatFromVal (cond->operand.valOperand);
3399 caseVal = (int) floatFromVal (caseVals);
3400 if (caseVal == switchVal)
3402 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3403 tree->values.switchVals.swNum, caseVal);
3404 trueLabel = newiTempLabel (buffer);
3405 geniCodeGoto (trueLabel);
3408 caseVals = caseVals->next;
3410 goto defaultOrBreak;
3413 /* if we can make this a jump table */
3414 if (geniCodeJumpTable (cond, caseVals, tree))
3415 goto jumpTable; /* no need for the comparison */
3417 /* for the cases defined do */
3421 operand *compare = geniCodeLogic (cond,
3422 operandFromValue (caseVals),
3425 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3426 tree->values.switchVals.swNum,
3427 (int) floatFromVal (caseVals));
3428 trueLabel = newiTempLabel (buffer);
3430 ic = newiCodeCondition (compare, trueLabel, NULL);
3432 caseVals = caseVals->next;
3437 /* if default is present then goto break else break */
3438 if (tree->values.switchVals.swDefault)
3440 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3444 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3447 falseLabel = newiTempLabel (buffer);
3448 geniCodeGoto (falseLabel);
3451 ast2iCode (tree->right,lvl+1);
3454 /*-----------------------------------------------------------------*/
3455 /* geniCodeInline - intermediate code for inline assembler */
3456 /*-----------------------------------------------------------------*/
3458 geniCodeInline (ast * tree)
3462 ic = newiCode (INLINEASM, NULL, NULL);
3463 IC_INLINE (ic) = tree->values.inlineasm;
3467 /*-----------------------------------------------------------------*/
3468 /* geniCodeArrayInit - intermediate code for array initializer */
3469 /*-----------------------------------------------------------------*/
3471 geniCodeArrayInit (ast * tree, operand *array)
3475 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3476 ic = newiCode (ARRAYINIT, array, NULL);
3477 IC_ARRAYILIST (ic) = tree->values.constlist;
3479 operand *left=newOperand(), *right=newOperand();
3480 left->type=right->type=SYMBOL;
3481 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3482 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3483 ic = newiCode (ARRAYINIT, left, right);
3488 /*-----------------------------------------------------------------*/
3489 /* geniCodeCritical - intermediate code for a critical statement */
3490 /*-----------------------------------------------------------------*/
3492 geniCodeCritical (ast *tree, int lvl)
3497 /* If op is NULL, the original interrupt state will saved on */
3498 /* the stack. Otherwise, it will be saved in op. */
3500 /* Generate a save of the current interrupt state & disabled */
3501 ic = newiCode (CRITICAL, NULL, NULL);
3502 IC_RESULT (ic) = op;
3505 /* Generate the critical code sequence */
3506 if (tree->left && tree->left->type == EX_VALUE)
3507 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3509 ast2iCode (tree->left,lvl+1);
3511 /* Generate a restore of the original interrupt state */
3512 ic = newiCode (ENDCRITICAL, NULL, op);
3516 /*-----------------------------------------------------------------*/
3517 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3518 /* particular case. Ie : assigning or dereferencing array or ptr */
3519 /*-----------------------------------------------------------------*/
3520 set * lvaluereqSet = NULL;
3521 typedef struct lvalItem
3528 /*-----------------------------------------------------------------*/
3529 /* addLvaluereq - add a flag for lvalreq for current ast level */
3530 /*-----------------------------------------------------------------*/
3531 void addLvaluereq(int lvl)
3533 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3536 addSetHead(&lvaluereqSet,lpItem);
3539 /*-----------------------------------------------------------------*/
3540 /* delLvaluereq - del a flag for lvalreq for current ast level */
3541 /*-----------------------------------------------------------------*/
3545 lpItem = getSet(&lvaluereqSet);
3546 if(lpItem) Safe_free(lpItem);
3548 /*-----------------------------------------------------------------*/
3549 /* clearLvaluereq - clear lvalreq flag */
3550 /*-----------------------------------------------------------------*/
3551 void clearLvaluereq()
3554 lpItem = peekSet(lvaluereqSet);
3555 if(lpItem) lpItem->req = 0;
3557 /*-----------------------------------------------------------------*/
3558 /* getLvaluereq - get the last lvalreq level */
3559 /*-----------------------------------------------------------------*/
3560 int getLvaluereqLvl()
3563 lpItem = peekSet(lvaluereqSet);
3564 if(lpItem) return lpItem->lvl;
3567 /*-----------------------------------------------------------------*/
3568 /* isLvaluereq - is lvalreq valid for this level ? */
3569 /*-----------------------------------------------------------------*/
3570 int isLvaluereq(int lvl)
3573 lpItem = peekSet(lvaluereqSet);
3574 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3578 /*-----------------------------------------------------------------*/
3579 /* ast2iCode - creates an icodeList from an ast */
3580 /*-----------------------------------------------------------------*/
3582 ast2iCode (ast * tree,int lvl)
3584 operand *left = NULL;
3585 operand *right = NULL;
3589 /* set the global variables for filename & line number */
3591 filename = tree->filename;
3593 lineno = tree->lineno;
3595 block = tree->block;
3597 scopeLevel = tree->level;
3599 seqPoint = tree->seqPoint;
3601 if (tree->type == EX_VALUE)
3602 return operandFromValue (tree->opval.val);
3604 if (tree->type == EX_LINK)
3605 return operandFromLink (tree->opval.lnk);
3607 /* if we find a nullop */
3608 if (tree->type == EX_OP &&
3609 (tree->opval.op == NULLOP ||
3610 tree->opval.op == BLOCK))
3612 if (tree->left && tree->left->type == EX_VALUE)
3613 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3615 ast2iCode (tree->left,lvl+1);
3616 if (tree->right && tree->right->type == EX_VALUE)
3617 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3619 ast2iCode (tree->right,lvl+1);
3623 /* special cases for not evaluating */
3624 if (tree->opval.op != ':' &&
3625 tree->opval.op != '?' &&
3626 tree->opval.op != CALL &&
3627 tree->opval.op != IFX &&
3628 tree->opval.op != LABEL &&
3629 tree->opval.op != GOTO &&
3630 tree->opval.op != SWITCH &&
3631 tree->opval.op != FUNCTION &&
3632 tree->opval.op != INLINEASM &&
3633 tree->opval.op != CRITICAL)
3636 if (IS_ASSIGN_OP (tree->opval.op) ||
3637 IS_DEREF_OP (tree) ||
3638 (tree->opval.op == '&' && !tree->right) ||
3639 tree->opval.op == PTR_OP)
3642 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3643 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3646 left = operandFromAst (tree->left,lvl);
3648 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3649 left = geniCodeRValue (left, TRUE);
3653 left = operandFromAst (tree->left,lvl);
3655 if (tree->opval.op == INC_OP ||
3656 tree->opval.op == DEC_OP)
3659 right = operandFromAst (tree->right,lvl);
3664 right = operandFromAst (tree->right,lvl);
3668 /* now depending on the type of operand */
3669 /* this will be a biggy */
3670 switch (tree->opval.op)
3673 case '[': /* array operation */
3675 //sym_link *ltype = operandType (left);
3676 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3677 left = geniCodeRValue (left, FALSE);
3678 right = geniCodeRValue (right, TRUE);
3681 return geniCodeArray (left, right,lvl);
3683 case '.': /* structure dereference */
3684 if (IS_PTR (operandType (left)))
3685 left = geniCodeRValue (left, TRUE);
3687 left = geniCodeRValue (left, FALSE);
3689 return geniCodeStruct (left, right, tree->lvalue);
3691 case PTR_OP: /* structure pointer dereference */
3694 pType = operandType (left);
3695 left = geniCodeRValue (left, TRUE);
3697 setOClass (pType, getSpec (operandType (left)));
3700 return geniCodeStruct (left, right, tree->lvalue);
3702 case INC_OP: /* increment operator */
3704 return geniCodePostInc (left);
3706 return geniCodePreInc (right, tree->lvalue);
3708 case DEC_OP: /* decrement operator */
3710 return geniCodePostDec (left);
3712 return geniCodePreDec (right, tree->lvalue);
3714 case '&': /* bitwise and or address of operator */
3716 { /* this is a bitwise operator */
3717 left = geniCodeRValue (left, FALSE);
3718 right = geniCodeRValue (right, FALSE);
3719 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3722 return geniCodeAddressOf (left);
3724 case '|': /* bitwise or & xor */
3726 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3727 geniCodeRValue (right, FALSE),
3732 return geniCodeDivision (geniCodeRValue (left, FALSE),
3733 geniCodeRValue (right, FALSE));
3736 return geniCodeModulus (geniCodeRValue (left, FALSE),
3737 geniCodeRValue (right, FALSE));
3740 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3741 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3743 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3747 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3748 geniCodeRValue (right, FALSE));
3750 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3754 return geniCodeAdd (geniCodeRValue (left, FALSE),
3755 geniCodeRValue (right, FALSE),lvl);
3757 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3760 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3761 geniCodeRValue (right, FALSE));
3764 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3765 geniCodeRValue (right, FALSE));
3767 #if 0 // this indeed needs a second thought
3771 // let's keep this simple: get the rvalue we need
3772 op=geniCodeRValue (right, FALSE);
3773 // now cast it to whatever we want
3774 op=geniCodeCast (operandType(left), op, FALSE);
3775 // if this is going to be used as an lvalue, make it so
3781 #else // bug #604575, is it a bug ????
3782 return geniCodeCast (operandType (left),
3783 geniCodeRValue (right, FALSE), FALSE);
3790 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3795 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3796 setOperandType (op, UCHARTYPE);
3807 /* different compilers (even different gccs) evaluate
3808 the two calls in a different order. to get the same
3809 result on all machines we've to specify a clear sequence.
3810 return geniCodeLogic (geniCodeRValue (left, FALSE),
3811 geniCodeRValue (right, FALSE),
3815 operand *leftOp, *rightOp;
3817 rightOp = geniCodeRValue (right, FALSE);
3818 leftOp = geniCodeRValue (left , FALSE);
3820 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3823 return geniCodeConditional (tree,lvl);
3826 return operandFromLit (getSize (tree->right->ftype));
3830 sym_link *rtype = operandType (right);
3831 sym_link *ltype = operandType (left);
3832 if (IS_PTR (rtype) && IS_ITEMP (right)
3833 && right->isaddr && compareType (rtype->next, ltype) == 1)
3834 right = geniCodeRValue (right, TRUE);
3836 right = geniCodeRValue (right, FALSE);
3838 geniCodeAssign (left, right, 0);
3843 geniCodeAssign (left,
3844 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3846 geniCodeRValue (right, FALSE),FALSE), 0);
3850 geniCodeAssign (left,
3851 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3853 geniCodeRValue (right, FALSE)), 0);
3856 geniCodeAssign (left,
3857 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3859 geniCodeRValue (right, FALSE)), 0);
3862 sym_link *rtype = operandType (right);
3863 sym_link *ltype = operandType (left);
3864 if (IS_PTR (rtype) && IS_ITEMP (right)
3865 && right->isaddr && compareType (rtype->next, ltype) == 1)
3866 right = geniCodeRValue (right, TRUE);
3868 right = geniCodeRValue (right, FALSE);
3871 return geniCodeAssign (left,
3872 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3878 sym_link *rtype = operandType (right);
3879 sym_link *ltype = operandType (left);
3880 if (IS_PTR (rtype) && IS_ITEMP (right)
3881 && right->isaddr && compareType (rtype->next, ltype) == 1)
3883 right = geniCodeRValue (right, TRUE);
3887 right = geniCodeRValue (right, FALSE);
3890 geniCodeAssign (left,
3891 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3897 geniCodeAssign (left,
3898 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3900 geniCodeRValue (right, FALSE)), 0);
3903 geniCodeAssign (left,
3904 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3906 geniCodeRValue (right, FALSE)), 0);
3909 geniCodeAssign (left,
3910 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3912 geniCodeRValue (right, FALSE),
3914 operandType (left)), 0);
3917 geniCodeAssign (left,
3918 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3920 geniCodeRValue (right, FALSE),
3922 operandType (left)), 0);
3925 geniCodeAssign (left,
3926 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3928 geniCodeRValue (right, FALSE),
3930 operandType (left)), 0);
3932 return geniCodeRValue (right, FALSE);
3935 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3938 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3939 return ast2iCode (tree->right,lvl+1);
3942 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3943 return ast2iCode (tree->right,lvl+1);
3946 geniCodeFunctionBody (tree,lvl);
3950 geniCodeReturn (right);
3954 geniCodeIfx (tree,lvl);
3958 geniCodeSwitch (tree,lvl);
3962 geniCodeInline (tree);
3966 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3970 geniCodeCritical (tree, lvl);
3976 /*-----------------------------------------------------------------*/
3977 /* reverseICChain - gets from the list and creates a linkedlist */
3978 /*-----------------------------------------------------------------*/
3985 while ((loop = getSet (&iCodeChain)))
3997 /*-----------------------------------------------------------------*/
3998 /* iCodeFromAst - given an ast will convert it to iCode */
3999 /*-----------------------------------------------------------------*/
4001 iCodeFromAst (ast * tree)
4003 returnLabel = newiTempLabel ("_return");
4004 entryLabel = newiTempLabel ("_entry");
4006 return reverseiCChain ();
4009 static const char *opTypeToStr(OPTYPE op)
4013 case SYMBOL: return "symbol";
4014 case VALUE: return "value";
4015 case TYPE: return "type";
4017 return "undefined type";
4021 operand *validateOpType(operand *op,
4028 if (op && op->type == type)
4033 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4034 " expected %s, got %s\n",
4035 macro, args, file, line,
4036 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4038 return op; // never reached, makes compiler happy.