1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
42 symbol *returnLabel; /* function return label */
43 symbol *entryLabel; /* function entry label */
45 /*-----------------------------------------------------------------*/
46 /* forward definition of some functions */
47 operand *geniCodeDivision (operand *, operand *);
48 operand *geniCodeAssign (operand *, operand *, int);
49 operand *geniCodeArray (operand *, operand *,int);
50 operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
54 void setOClass (sym_link * ptr, sym_link * spec);
56 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
57 /* forward definition of ic print functions */
58 PRINTFUNC (picGetValueAtAddr);
59 PRINTFUNC (picSetValueAtAddr);
60 PRINTFUNC (picAddrOf);
61 PRINTFUNC (picGeneric);
62 PRINTFUNC (picGenericOne);
64 PRINTFUNC (picAssign);
68 PRINTFUNC (picJumpTable);
69 PRINTFUNC (picInline);
70 PRINTFUNC (picReceive);
71 PRINTFUNC (picDummyRead);
72 PRINTFUNC (picCritical);
73 PRINTFUNC (picEndCritical);
75 iCodeTable codeTable[] =
77 {'!', "not", picGenericOne, NULL},
78 {'~', "~", picGenericOne, NULL},
79 {RRC, "rrc", picGenericOne, NULL},
80 {RLC, "rlc", picGenericOne, NULL},
81 {GETHBIT, "ghbit", picGenericOne, NULL},
82 {UNARYMINUS, "-", picGenericOne, NULL},
83 {IPUSH, "push", picGenericOne, NULL},
84 {IPOP, "pop", picGenericOne, NULL},
85 {CALL, "call", picGenericOne, NULL},
86 {PCALL, "pcall", picGenericOne, NULL},
87 {FUNCTION, "proc", picGenericOne, NULL},
88 {ENDFUNCTION, "eproc", picGenericOne, NULL},
89 {RETURN, "ret", picGenericOne, NULL},
90 {'+', "+", picGeneric, NULL},
91 {'-', "-", picGeneric, NULL},
92 {'*', "*", picGeneric, NULL},
93 {'/', "/", picGeneric, NULL},
94 {'%', "%", picGeneric, NULL},
95 {'>', ">", picGeneric, NULL},
96 {'<', "<", picGeneric, NULL},
97 {LE_OP, "<=", picGeneric, NULL},
98 {GE_OP, ">=", picGeneric, NULL},
99 {EQ_OP, "==", picGeneric, NULL},
100 {NE_OP, "!=", picGeneric, NULL},
101 {AND_OP, "&&", picGeneric, NULL},
102 {OR_OP, "||", picGeneric, NULL},
103 {'^', "^", picGeneric, NULL},
104 {'|', "|", picGeneric, NULL},
105 {BITWISEAND, "&", picGeneric, NULL},
106 {LEFT_OP, "<<", picGeneric, NULL},
107 {RIGHT_OP, ">>", picGeneric, NULL},
108 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
109 {ADDRESS_OF, "&", picAddrOf, NULL},
110 {CAST, "<>", picCast, NULL},
111 {'=', ":=", picAssign, NULL},
112 {LABEL, "", picLabel, NULL},
113 {GOTO, "", picGoto, NULL},
114 {JUMPTABLE, "jtab", picJumpTable, NULL},
115 {IFX, "if", picIfx, NULL},
116 {INLINEASM, "", picInline, NULL},
117 {RECEIVE, "recv", picReceive, NULL},
118 {SEND, "send", picGenericOne, NULL},
119 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
120 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
121 {CRITICAL, "critical_start", picCritical, NULL},
122 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
125 /*-----------------------------------------------------------------*/
126 /* checkConstantRange: check a constant against the type */
127 /*-----------------------------------------------------------------*/
130 /* pedantic=0: allmost anything is allowed as long as the absolute
131 value is within the bit range of the type, and -1 is treated as
132 0xf..f for unsigned types (e.g. in assign)
133 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
134 pedantic>1: "char c=200" is not allowed (evaluates to -56)
137 void checkConstantRange(sym_link *ltype, value *val, char *msg,
144 max = pow ((double)2.0, (double)bitsForType(ltype));
146 if (SPEC_LONG(val->type)) {
147 if (SPEC_USIGN(val->type)) {
148 v=SPEC_CVAL(val->type).v_ulong;
150 v=SPEC_CVAL(val->type).v_long;
153 if (SPEC_USIGN(val->type)) {
154 v=SPEC_CVAL(val->type).v_uint;
156 v=SPEC_CVAL(val->type).v_int;
162 // this could be a good idea
163 if (options.pedantic)
167 if (SPEC_NOUN(ltype)==FLOAT) {
172 if (!SPEC_USIGN(val->type) && v<0) {
174 if (SPEC_USIGN(ltype) && (pedantic>1)) {
180 // if very pedantic: "char c=200" is not allowed
181 if (pedantic>1 && !SPEC_USIGN(ltype)) {
182 max = max/2 + negative;
189 #if 0 // temporary disabled, leaving the warning as a reminder
191 SNPRINTF (message, sizeof(message), "for %s %s in %s",
192 SPEC_USIGN(ltype) ? "unsigned" : "signed",
193 nounName(ltype), msg);
194 werror (W_CONST_RANGE, message);
202 /*-----------------------------------------------------------------*/
203 /* operandName - returns the name of the operand */
204 /*-----------------------------------------------------------------*/
206 printOperand (operand * op, FILE * file)
223 opetype = getSpec (operandType (op));
224 if (SPEC_NOUN (opetype) == V_FLOAT)
225 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
227 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
228 printTypeChain (operandType (op), file);
235 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}" , */
236 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
238 OP_LIVEFROM (op), OP_LIVETO (op),
239 OP_SYMBOL (op)->stack,
240 op->isaddr, OP_SYMBOL (op)->isreqv,
241 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
242 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
246 printTypeChain (operandType (op), file);
247 if (SPIL_LOC (op) && IS_ITEMP (op))
248 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
253 /* if assigned to registers */
254 if (OP_SYMBOL (op)->nRegs)
256 if (OP_SYMBOL (op)->isspilt)
258 if (!OP_SYMBOL (op)->remat)
259 if (OP_SYMBOL (op)->usl.spillLoc)
260 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
261 OP_SYMBOL (op)->usl.spillLoc->rname :
262 OP_SYMBOL (op)->usl.spillLoc->name));
264 fprintf (file, "[err]");
266 fprintf (file, "[remat]");
272 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
273 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
278 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
279 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
280 /* if assigned to registers */
281 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
285 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
286 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
287 OP_SYMBOL (op)->regs[i]->name :
296 printTypeChain (op->operand.typeOperand, file);
302 fprintf (file, "\n");
307 /*-----------------------------------------------------------------*/
308 /* print functions */
309 /*-----------------------------------------------------------------*/
310 PRINTFUNC (picGetValueAtAddr)
313 printOperand (IC_RESULT (ic), of);
316 printOperand (IC_LEFT (ic), of);
322 PRINTFUNC (picSetValueAtAddr)
326 printOperand (IC_LEFT (ic), of);
327 fprintf (of, "] = ");
328 printOperand (IC_RIGHT (ic), of);
332 PRINTFUNC (picAddrOf)
335 printOperand (IC_RESULT (ic), of);
336 if (IS_ITEMP (IC_LEFT (ic)))
339 fprintf (of, " = &[");
340 printOperand (IC_LEFT (ic), of);
343 if (IS_ITEMP (IC_LEFT (ic)))
344 fprintf (of, " offsetAdd ");
347 printOperand (IC_RIGHT (ic), of);
349 if (IS_ITEMP (IC_LEFT (ic)))
355 PRINTFUNC (picJumpTable)
360 fprintf (of, "%s\t", s);
361 printOperand (IC_JTCOND (ic), of);
363 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
364 sym = setNextItem (IC_JTLABELS (ic)))
365 fprintf (of, "\t\t\t%s\n", sym->name);
368 PRINTFUNC (picGeneric)
371 printOperand (IC_RESULT (ic), of);
373 printOperand (IC_LEFT (ic), of);
374 fprintf (of, " %s ", s);
375 printOperand (IC_RIGHT (ic), of);
379 PRINTFUNC (picGenericOne)
384 printOperand (IC_RESULT (ic), of);
390 fprintf (of, "%s ", s);
391 printOperand (IC_LEFT (ic), of);
394 if (!IC_RESULT (ic) && !IC_LEFT (ic))
397 if (ic->op == SEND || ic->op == RECEIVE) {
398 fprintf(of,"{argreg = %d}",ic->argreg);
406 printOperand (IC_RESULT (ic), of);
408 printOperand (IC_LEFT (ic), of);
409 printOperand (IC_RIGHT (ic), of);
414 PRINTFUNC (picAssign)
418 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
421 printOperand (IC_RESULT (ic), of);
423 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
426 fprintf (of, " %s ", s);
427 printOperand (IC_RIGHT (ic), of);
434 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
440 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
447 printOperand (IC_COND (ic), of);
450 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
453 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
455 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
459 PRINTFUNC (picInline)
461 fprintf (of, "%s", IC_INLINE (ic));
464 PRINTFUNC (picReceive)
466 printOperand (IC_RESULT (ic), of);
467 fprintf (of, " = %s ", s);
468 printOperand (IC_LEFT (ic), of);
472 PRINTFUNC (picDummyRead)
475 fprintf (of, "%s ", s);
476 printOperand (IC_RIGHT (ic), of);
480 PRINTFUNC (picCritical)
484 printOperand (IC_RESULT (ic), of);
486 fprintf (of, "(stack)");
487 fprintf (of, " = %s ", s);
491 PRINTFUNC (picEndCritical)
494 fprintf (of, "%s = ", s);
496 printOperand (IC_RIGHT (ic), of);
498 fprintf (of, "(stack)");
502 /*-----------------------------------------------------------------*/
503 /* piCode - prints one iCode */
504 /*-----------------------------------------------------------------*/
506 piCode (void *item, FILE * of)
514 icTab = getTableEntry (ic->op);
515 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
516 ic->filename, ic->lineno,
517 ic->seq, ic->key, ic->depth, ic->supportRtn);
518 icTab->iCodePrint (of, ic, icTab->printName);
524 printiCChain(ic,stdout);
526 /*-----------------------------------------------------------------*/
527 /* printiCChain - prints intermediate code for humans */
528 /*-----------------------------------------------------------------*/
530 printiCChain (iCode * icChain, FILE * of)
537 for (loop = icChain; loop; loop = loop->next)
539 if ((icTab = getTableEntry (loop->op)))
541 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
542 loop->filename, loop->lineno,
543 loop->seq, loop->key, loop->depth, loop->supportRtn);
545 icTab->iCodePrint (of, loop, icTab->printName);
551 /*-----------------------------------------------------------------*/
552 /* newOperand - allocate, init & return a new iCode */
553 /*-----------------------------------------------------------------*/
559 op = Safe_alloc ( sizeof (operand));
565 /*-----------------------------------------------------------------*/
566 /* newiCode - create and return a new iCode entry initialised */
567 /*-----------------------------------------------------------------*/
569 newiCode (int op, operand * left, operand * right)
573 ic = Safe_alloc ( sizeof (iCode));
576 ic->filename = filename;
578 ic->level = scopeLevel;
580 ic->key = iCodeKey++;
582 IC_RIGHT (ic) = right;
587 /*-----------------------------------------------------------------*/
588 /* newiCode for conditional statements */
589 /*-----------------------------------------------------------------*/
591 newiCodeCondition (operand * condition,
597 if (IS_VOID(operandType(condition))) {
598 werror(E_VOID_VALUE_USED);
601 ic = newiCode (IFX, NULL, NULL);
602 IC_COND (ic) = condition;
603 IC_TRUE (ic) = trueLabel;
604 IC_FALSE (ic) = falseLabel;
608 /*-----------------------------------------------------------------*/
609 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
610 /*-----------------------------------------------------------------*/
612 newiCodeLabelGoto (int op, symbol * label)
616 ic = newiCode (op, NULL, NULL);
620 IC_RIGHT (ic) = NULL;
621 IC_RESULT (ic) = NULL;
625 /*-----------------------------------------------------------------*/
626 /* newiTemp - allocate & return a newItemp Variable */
627 /*-----------------------------------------------------------------*/
635 SNPRINTF (buffer, sizeof(buffer), "%s", s);
639 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
642 itmp = newSymbol (buffer, 1);
643 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
649 /*-----------------------------------------------------------------*/
650 /* newiTempLabel - creates a temp variable label */
651 /*-----------------------------------------------------------------*/
653 newiTempLabel (char *s)
657 /* check if this alredy exists */
658 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
663 itmplbl = newSymbol (s, 1);
667 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
668 itmplbl = newSymbol (buffer, 1);
673 itmplbl->key = labelKey++;
674 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
678 /*-----------------------------------------------------------------*/
679 /* newiTempPreheaderLabel - creates a new preheader label */
680 /*-----------------------------------------------------------------*/
682 newiTempPreheaderLabel ()
686 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
687 itmplbl = newSymbol (buffer, 1);
691 itmplbl->key = labelKey++;
692 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
697 /*-----------------------------------------------------------------*/
698 /* initiCode - initialises some iCode related stuff */
699 /*-----------------------------------------------------------------*/
706 /*-----------------------------------------------------------------*/
707 /* copyiCode - make a copy of the iCode given */
708 /*-----------------------------------------------------------------*/
710 copyiCode (iCode * ic)
712 iCode *nic = newiCode (ic->op, NULL, NULL);
714 nic->lineno = ic->lineno;
715 nic->filename = ic->filename;
716 nic->block = ic->block;
717 nic->level = ic->level;
718 nic->parmBytes = ic->parmBytes;
720 /* deal with the special cases first */
724 IC_COND (nic) = operandFromOperand (IC_COND (ic));
725 IC_TRUE (nic) = IC_TRUE (ic);
726 IC_FALSE (nic) = IC_FALSE (ic);
730 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
731 IC_JTLABELS (nic) = IC_JTLABELS (ic);
736 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
737 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
741 IC_INLINE (nic) = IC_INLINE (ic);
745 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
749 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
750 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
751 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
757 /*-----------------------------------------------------------------*/
758 /* getTableEntry - gets the table entry for the given operator */
759 /*-----------------------------------------------------------------*/
761 getTableEntry (int oper)
765 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
766 if (oper == codeTable[i].icode)
767 return &codeTable[i];
772 /*-----------------------------------------------------------------*/
773 /* newiTempOperand - new intermediate temp operand */
774 /*-----------------------------------------------------------------*/
776 newiTempOperand (sym_link * type, char throwType)
779 operand *op = newOperand ();
783 itmp = newiTemp (NULL);
785 etype = getSpec (type);
787 if (IS_LITERAL (etype))
790 /* copy the type information */
792 itmp->etype = getSpec (itmp->type = (throwType ? type :
793 copyLinkChain (type)));
794 if (IS_LITERAL (itmp->etype))
796 SPEC_SCLS (itmp->etype) = S_REGISTER;
797 SPEC_OCLS (itmp->etype) = reg;
800 op->operand.symOperand = itmp;
801 op->key = itmp->key = ++operandKey;
805 /*-----------------------------------------------------------------*/
806 /* operandType - returns the type chain for an operand */
807 /*-----------------------------------------------------------------*/
809 operandType (operand * op)
811 /* depending on type of operand */
816 return op->operand.valOperand->type;
819 return op->operand.symOperand->type;
822 return op->operand.typeOperand;
824 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
825 " operand type not known ");
826 assert (0); /* should never come here */
827 /* Just to keep the compiler happy */
828 return (sym_link *) 0;
832 /*-----------------------------------------------------------------*/
833 /* isParamterToCall - will return 1 if op is a parameter to args */
834 /*-----------------------------------------------------------------*/
836 isParameterToCall (value * args, operand * op)
840 wassert (IS_SYMOP(op));
845 isSymbolEqual (op->operand.symOperand, tval->sym))
852 /*-----------------------------------------------------------------*/
853 /* isOperandGlobal - return 1 if operand is a global variable */
854 /*-----------------------------------------------------------------*/
856 isOperandGlobal (operand * op)
865 (op->operand.symOperand->level == 0 ||
866 IS_STATIC (op->operand.symOperand->etype) ||
867 IS_EXTERN (op->operand.symOperand->etype))
874 /*-----------------------------------------------------------------*/
875 /* isOperandVolatile - return 1 if the operand is volatile */
876 /*-----------------------------------------------------------------*/
878 isOperandVolatile (operand * op, bool chkTemp)
883 if (IS_ITEMP (op) && !chkTemp)
886 opetype = getSpec (optype = operandType (op));
888 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
891 if (IS_VOLATILE (opetype))
896 /*-----------------------------------------------------------------*/
897 /* isOperandLiteral - returns 1 if an operand contains a literal */
898 /*-----------------------------------------------------------------*/
900 isOperandLiteral (operand * op)
907 opetype = getSpec (operandType (op));
909 if (IS_LITERAL (opetype))
915 /*-----------------------------------------------------------------*/
916 /* isOperandInFarSpace - will return true if operand is in farSpace */
917 /*-----------------------------------------------------------------*/
919 isOperandInFarSpace (operand * op)
929 if (!IS_TRUE_SYMOP (op))
932 etype = SPIL_LOC (op)->etype;
938 etype = getSpec (operandType (op));
940 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
943 /*------------------------------------------------------------------*/
944 /* isOperandInDirSpace - will return true if operand is in dirSpace */
945 /*------------------------------------------------------------------*/
947 isOperandInDirSpace (operand * op)
957 if (!IS_TRUE_SYMOP (op))
960 etype = SPIL_LOC (op)->etype;
966 etype = getSpec (operandType (op));
968 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
971 /*--------------------------------------------------------------------*/
972 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
973 /*--------------------------------------------------------------------*/
975 isOperandInCodeSpace (operand * op)
985 etype = getSpec (operandType (op));
987 if (!IS_TRUE_SYMOP (op))
990 etype = SPIL_LOC (op)->etype;
996 etype = getSpec (operandType (op));
998 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1001 /*-----------------------------------------------------------------*/
1002 /* isOperandOnStack - will return true if operand is on stack */
1003 /*-----------------------------------------------------------------*/
1005 isOperandOnStack (operand * op)
1015 etype = getSpec (operandType (op));
1016 if (IN_STACK (etype) ||
1017 OP_SYMBOL(op)->onStack ||
1018 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1024 /*-----------------------------------------------------------------*/
1025 /* isOclsExpensive - will return true if accesses to an output */
1026 /* storage class are expensive */
1027 /*-----------------------------------------------------------------*/
1029 isOclsExpensive (struct memmap *oclass)
1031 if (port->oclsExpense)
1032 return port->oclsExpense (oclass) > 0;
1034 /* In the absence of port specific guidance, assume only */
1035 /* farspace is expensive. */
1036 return IN_FARSPACE (oclass);
1039 /*-----------------------------------------------------------------*/
1040 /* operandLitValue - literal value of an operand */
1041 /*-----------------------------------------------------------------*/
1043 operandLitValue (operand * op)
1045 assert (isOperandLiteral (op));
1047 return floatFromVal (op->operand.valOperand);
1050 /*-----------------------------------------------------------------*/
1051 /* getBuiltInParms - returns parameters to a builtin functions */
1052 /*-----------------------------------------------------------------*/
1053 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1058 /* builtin functions uses only SEND for parameters */
1059 while (ic->op != CALL) {
1060 assert(ic->op == SEND && ic->builtinSEND);
1061 ic->generated = 1; /* mark the icode as generated */
1062 parms[*pcount] = IC_LEFT(ic);
1068 /* make sure this is a builtin function call */
1069 assert(IS_SYMOP(IC_LEFT(ic)));
1070 ftype = operandType(IC_LEFT(ic));
1071 assert(IFFUNC_ISBUILTIN(ftype));
1075 /*-----------------------------------------------------------------*/
1076 /* operandOperation - performs operations on operands */
1077 /*-----------------------------------------------------------------*/
1079 operandOperation (operand * left, operand * right,
1080 int op, sym_link * type)
1082 sym_link *let , *ret=NULL;
1083 operand *retval = (operand *) 0;
1085 assert (isOperandLiteral (left));
1086 let = getSpec(operandType(left));
1088 assert (isOperandLiteral (right));
1089 ret = getSpec(operandType(right));
1095 retval = operandFromValue (valCastLiteral (type,
1096 operandLitValue (left) +
1097 operandLitValue (right)));
1100 retval = operandFromValue (valCastLiteral (type,
1101 operandLitValue (left) -
1102 operandLitValue (right)));
1106 retval = operandFromValue (valCastLiteral (type,
1107 operandLitValue (left) *
1108 operandLitValue (right)));
1109 This could be all we've to do, but with gcc we've to take care about
1110 overflows. Two examples:
1111 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1112 significant bits are lost (52 in fraction, 63 bits would be
1113 necessary to keep full precision).
1114 If the resulting double value is greater than ULONG_MAX (resp.
1115 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1118 /* if it is not a specifier then we can assume that */
1119 /* it will be an unsigned long */
1120 if (IS_INT (type) ||
1123 /* long is handled here, because it can overflow with double */
1124 if (SPEC_LONG (type) ||
1126 /* signed and unsigned mul are the same, as long as the precision
1127 of the result isn't bigger than the precision of the operands. */
1128 retval = operandFromValue (valCastLiteral (type,
1129 (TYPE_UDWORD) operandLitValue (left) *
1130 (TYPE_UDWORD) operandLitValue (right)));
1131 else if (SPEC_USIGN (type)) /* unsigned int */
1133 /* unsigned int is handled here in order to detect overflow */
1134 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1135 (TYPE_UWORD) operandLitValue (right);
1137 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1138 if (ul != (TYPE_UWORD) ul)
1141 else /* signed int */
1143 /* signed int is handled here in order to detect overflow */
1144 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1145 (TYPE_WORD) operandLitValue (right);
1147 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1148 if (l != (TYPE_WORD) l)
1153 /* all others go here: */
1154 retval = operandFromValue (valCastLiteral (type,
1155 operandLitValue (left) *
1156 operandLitValue (right)));
1159 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1161 werror (E_DIVIDE_BY_ZERO);
1166 retval = operandFromValue (valCastLiteral (type,
1167 operandLitValue (left) /
1168 operandLitValue (right)));
1171 if ((TYPE_UDWORD) operandLitValue (right) == 0) {
1172 werror (E_DIVIDE_BY_ZERO);
1177 if (SPEC_USIGN(let) || SPEC_USIGN(ret))
1178 /* one of the operands is unsigned */
1179 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1180 (TYPE_UDWORD) operandLitValue (right));
1182 /* both operands are signed */
1183 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1184 (TYPE_DWORD) operandLitValue (right));
1188 /* The number of left shifts is always unsigned. Signed doesn't make
1189 sense here. Shifting by a negative number is impossible. */
1190 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1191 (TYPE_UDWORD) operandLitValue (right));
1194 /* The number of right shifts is always unsigned. Signed doesn't make
1195 sense here. Shifting by a negative number is impossible. */
1196 if (SPEC_USIGN(let))
1197 /* unsigned: logic shift right */
1198 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1199 (TYPE_UDWORD) operandLitValue (right));
1201 /* signed: arithmetic shift right */
1202 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1203 (TYPE_UDWORD) operandLitValue (right));
1206 /* this op doesn't care about signedness */
1210 l = (TYPE_UDWORD) operandLitValue (left);
1211 if (SPEC_NOUN(OP_VALUE(left)->type) == V_CHAR)
1213 else if (!SPEC_LONG (OP_VALUE(left)->type))
1215 r = (TYPE_UDWORD) operandLitValue (right);
1216 if (SPEC_NOUN(OP_VALUE(right)->type) == V_CHAR)
1218 else if (!SPEC_LONG (OP_VALUE(right)->type))
1220 retval = operandFromLit (l == r);
1224 retval = operandFromLit (operandLitValue (left) <
1225 operandLitValue (right));
1228 retval = operandFromLit (operandLitValue (left) <=
1229 operandLitValue (right));
1232 retval = operandFromLit (operandLitValue (left) !=
1233 operandLitValue (right));
1236 retval = operandFromLit (operandLitValue (left) >
1237 operandLitValue (right));
1240 retval = operandFromLit (operandLitValue (left) >=
1241 operandLitValue (right));
1244 retval = operandFromValue (valCastLiteral (type,
1245 (TYPE_UDWORD)operandLitValue(left) &
1246 (TYPE_UDWORD)operandLitValue(right)));
1249 retval = operandFromValue (valCastLiteral (type,
1250 (TYPE_UDWORD)operandLitValue(left) |
1251 (TYPE_UDWORD)operandLitValue(right)));
1254 retval = operandFromValue (valCastLiteral (type,
1255 (TYPE_UDWORD)operandLitValue(left) ^
1256 (TYPE_UDWORD)operandLitValue(right)));
1259 retval = operandFromLit (operandLitValue (left) &&
1260 operandLitValue (right));
1263 retval = operandFromLit (operandLitValue (left) ||
1264 operandLitValue (right));
1268 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1270 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1276 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1278 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1284 retval = operandFromValue (valCastLiteral (type,
1285 -1 * operandLitValue (left)));
1289 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1293 retval = operandFromLit (!operandLitValue (left));
1297 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1298 " operandOperation invalid operator ");
1306 /*-----------------------------------------------------------------*/
1307 /* isOperandEqual - compares two operand & return 1 if they r = */
1308 /*-----------------------------------------------------------------*/
1310 isOperandEqual (operand * left, operand * right)
1312 /* if the pointers are equal then they are equal */
1316 /* if either of them null then false */
1317 if (!left || !right)
1320 if (left->type != right->type)
1323 if (IS_SYMOP (left) && IS_SYMOP (right))
1324 return left->key == right->key;
1326 /* if types are the same */
1330 return isSymbolEqual (left->operand.symOperand,
1331 right->operand.symOperand);
1333 return (floatFromVal (left->operand.valOperand) ==
1334 floatFromVal (right->operand.valOperand));
1336 if (compareType (left->operand.typeOperand,
1337 right->operand.typeOperand) == 1)
1344 /*-------------------------------------------------------------------*/
1345 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1346 /*-------------------------------------------------------------------*/
1348 isiCodeEqual (iCode * left, iCode * right)
1350 /* if the same pointer */
1354 /* if either of them null */
1355 if (!left || !right)
1358 /* if operand are the same */
1359 if (left->op == right->op)
1362 /* compare all the elements depending on type */
1363 if (left->op != IFX)
1365 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1367 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1373 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1375 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1377 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1386 /*-----------------------------------------------------------------*/
1387 /* newiTempFromOp - create a temp Operand with same attributes */
1388 /*-----------------------------------------------------------------*/
1390 newiTempFromOp (operand * op)
1400 nop = newiTempOperand (operandType (op), TRUE);
1401 nop->isaddr = op->isaddr;
1402 nop->isvolatile = op->isvolatile;
1403 nop->isGlobal = op->isGlobal;
1404 nop->isLiteral = op->isLiteral;
1405 nop->usesDefs = op->usesDefs;
1406 nop->isParm = op->isParm;
1410 /*-----------------------------------------------------------------*/
1411 /* operand from operand - creates an operand holder for the type */
1412 /*-----------------------------------------------------------------*/
1414 operandFromOperand (operand * op)
1420 nop = newOperand ();
1421 nop->type = op->type;
1422 nop->isaddr = op->isaddr;
1424 nop->isvolatile = op->isvolatile;
1425 nop->isGlobal = op->isGlobal;
1426 nop->isLiteral = op->isLiteral;
1427 nop->usesDefs = op->usesDefs;
1428 nop->isParm = op->isParm;
1433 nop->operand.symOperand = op->operand.symOperand;
1436 nop->operand.valOperand = op->operand.valOperand;
1439 nop->operand.typeOperand = op->operand.typeOperand;
1446 /*-----------------------------------------------------------------*/
1447 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1448 /*-----------------------------------------------------------------*/
1450 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1452 operand *nop = operandFromOperand (op);
1454 if (nop->type == SYMBOL)
1456 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1457 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1463 /*-----------------------------------------------------------------*/
1464 /* operandFromSymbol - creates an operand from a symbol */
1465 /*-----------------------------------------------------------------*/
1467 operandFromSymbol (symbol * sym)
1472 /* if the symbol's type is a literal */
1473 /* then it is an enumerator type */
1474 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1475 return operandFromValue (valFromType (sym->etype));
1478 sym->key = ++operandKey;
1480 /* if this an implicit variable, means struct/union */
1481 /* member so just return it */
1482 if (sym->implicit || IS_FUNC (sym->type))
1486 op->operand.symOperand = sym;
1488 op->isvolatile = isOperandVolatile (op, TRUE);
1489 op->isGlobal = isOperandGlobal (op);
1493 /* under the following conditions create a
1494 register equivalent for a local symbol */
1495 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1496 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1498 (!(options.model == MODEL_FLAT24)) ) &&
1499 options.stackAuto == 0)
1502 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1503 !IS_FUNC (sym->type) && /* not a function */
1504 !sym->_isparm && /* not a parameter */
1505 sym->level && /* is a local variable */
1506 !sym->addrtaken && /* whose address has not been taken */
1507 !sym->reqv && /* does not already have a reg equivalence */
1508 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1509 !IS_STATIC (sym->etype) && /* and not declared static */
1510 !sym->islbl && /* not a label */
1511 ok && /* farspace check */
1512 !IS_BITVAR (sym->etype) /* not a bit variable */
1516 /* we will use it after all optimizations
1517 and before liveRange calculation */
1518 sym->reqv = newiTempOperand (sym->type, 0);
1519 sym->reqv->key = sym->key;
1520 OP_SYMBOL (sym->reqv)->key = sym->key;
1521 OP_SYMBOL (sym->reqv)->isreqv = 1;
1522 OP_SYMBOL (sym->reqv)->islocal = 1;
1523 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1524 SPIL_LOC (sym->reqv) = sym;
1527 if (!IS_AGGREGATE (sym->type))
1531 op->operand.symOperand = sym;
1534 op->isvolatile = isOperandVolatile (op, TRUE);
1535 op->isGlobal = isOperandGlobal (op);
1536 op->isPtr = IS_PTR (operandType (op));
1537 op->isParm = sym->_isparm;
1542 /* itemp = &[_symbol] */
1544 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1545 IC_LEFT (ic)->type = SYMBOL;
1546 IC_LEFT (ic)->operand.symOperand = sym;
1547 IC_LEFT (ic)->key = sym->key;
1548 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1549 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1550 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1553 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1554 if (IS_ARRAY (sym->type))
1556 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1557 IC_RESULT (ic)->isaddr = 0;
1560 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1564 return IC_RESULT (ic);
1567 /*-----------------------------------------------------------------*/
1568 /* operandFromValue - creates an operand from value */
1569 /*-----------------------------------------------------------------*/
1571 operandFromValue (value * val)
1575 /* if this is a symbol then do the symbol thing */
1577 return operandFromSymbol (val->sym);
1579 /* this is not a symbol */
1582 op->operand.valOperand = val;
1583 op->isLiteral = isOperandLiteral (op);
1587 /*-----------------------------------------------------------------*/
1588 /* operandFromLink - operand from typeChain */
1589 /*-----------------------------------------------------------------*/
1591 operandFromLink (sym_link * type)
1595 /* operand from sym_link */
1601 op->operand.typeOperand = copyLinkChain (type);
1605 /*-----------------------------------------------------------------*/
1606 /* operandFromLit - makes an operand from a literal value */
1607 /*-----------------------------------------------------------------*/
1609 operandFromLit (double i)
1611 return operandFromValue (valueFromLit (i));
1614 /*-----------------------------------------------------------------*/
1615 /* operandFromAst - creates an operand from an ast */
1616 /*-----------------------------------------------------------------*/
1618 operandFromAst (ast * tree,int lvl)
1624 /* depending on type do */
1628 return ast2iCode (tree,lvl+1);
1632 return operandFromValue (tree->opval.val);
1636 return operandFromLink (tree->opval.lnk);
1643 /* Just to keep the compiler happy */
1644 return (operand *) 0;
1647 /*-----------------------------------------------------------------*/
1648 /* setOperandType - sets the operand's type to the given type */
1649 /*-----------------------------------------------------------------*/
1651 setOperandType (operand * op, sym_link * type)
1653 /* depending on the type of operand */
1658 op->operand.valOperand->etype =
1659 getSpec (op->operand.valOperand->type =
1660 copyLinkChain (type));
1664 if (op->operand.symOperand->isitmp)
1665 op->operand.symOperand->etype =
1666 getSpec (op->operand.symOperand->type =
1667 copyLinkChain (type));
1669 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1670 "attempt to modify type of source");
1674 op->operand.typeOperand = copyLinkChain (type);
1679 /*-----------------------------------------------------------------*/
1680 /* Get size in byte of ptr need to access an array */
1681 /*-----------------------------------------------------------------*/
1683 getArraySizePtr (operand * op)
1685 sym_link *ltype = operandType(op);
1689 int size = getSize(ltype);
1690 return(IS_GENPTR(ltype)?(size-1):size);
1695 sym_link *letype = getSpec(ltype);
1696 switch (PTR_TYPE (SPEC_OCLS (letype)))
1708 return (GPTRSIZE-1);
1717 /*-----------------------------------------------------------------*/
1718 /* perform "usual unary conversions" */
1719 /*-----------------------------------------------------------------*/
1721 usualUnaryConversions (operand * op)
1723 if (IS_INTEGRAL (operandType (op)))
1725 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1728 return geniCodeCast (INTTYPE, op, TRUE);
1734 /*-----------------------------------------------------------------*/
1735 /* perform "usual binary conversions" */
1736 /*-----------------------------------------------------------------*/
1738 usualBinaryConversions (operand ** op1, operand ** op2)
1741 sym_link *rtype = operandType (*op2);
1742 sym_link *ltype = operandType (*op1);
1744 ctype = computeType (ltype, rtype);
1746 *op1 = geniCodeCast (ctype, *op1, TRUE);
1747 *op2 = geniCodeCast (ctype, *op2, TRUE);
1752 /*-----------------------------------------------------------------*/
1753 /* geniCodeValueAtAddress - generate intermeditate code for value */
1755 /*-----------------------------------------------------------------*/
1757 geniCodeRValue (operand * op, bool force)
1760 sym_link *type = operandType (op);
1761 sym_link *etype = getSpec (type);
1763 /* if this is an array & already */
1764 /* an address then return this */
1765 if (IS_AGGREGATE (type) ||
1766 (IS_PTR (type) && !force && !op->isaddr))
1767 return operandFromOperand (op);
1769 /* if this is not an address then must be */
1770 /* rvalue already so return this one */
1774 /* if this is not a temp symbol then */
1775 if (!IS_ITEMP (op) &&
1777 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1779 op = operandFromOperand (op);
1784 if (IS_SPEC (type) &&
1785 IS_TRUE_SYMOP (op) &&
1786 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1787 (options.model == MODEL_FLAT24) ))
1789 op = operandFromOperand (op);
1794 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1795 if (IS_PTR (type) && op->isaddr && force)
1798 type = copyLinkChain (type);
1800 IC_RESULT (ic) = newiTempOperand (type, 1);
1801 IC_RESULT (ic)->isaddr = 0;
1803 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1807 return IC_RESULT (ic);
1810 /*-----------------------------------------------------------------*/
1811 /* geniCodeCast - changes the value from one type to another */
1812 /*-----------------------------------------------------------------*/
1814 geniCodeCast (sym_link * type, operand * op, bool implicit)
1818 sym_link *opetype = getSpec (optype = operandType (op));
1822 /* one of them has size zero then error */
1823 if (IS_VOID (optype))
1825 werror (E_CAST_ZERO);
1829 /* if the operand is already the desired type then do nothing */
1830 if (compareType (type, optype) == 1)
1833 /* if this is a literal then just change the type & return */
1834 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1835 return operandFromValue (valCastLiteral (type,
1836 operandLitValue (op)));
1838 /* if casting to/from pointers, do some checking */
1839 if (IS_PTR(type)) { // to a pointer
1840 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1841 if (IS_INTEGRAL(optype)) {
1842 // maybe this is NULL, than it's ok.
1843 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1844 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1845 // no way to set the storage
1846 if (IS_LITERAL(optype)) {
1847 werror(E_LITERAL_GENERIC);
1850 werror(E_NONPTR2_GENPTR);
1853 } else if (implicit) {
1854 werror(W_INTEGRAL2PTR_NOCAST);
1859 // shouldn't do that with float, array or structure unless to void
1860 if (!IS_VOID(getSpec(type)) &&
1861 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1862 werror(E_INCOMPAT_TYPES);
1866 } else { // from a pointer to a pointer
1867 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1868 // if not a pointer to a function
1869 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1870 if (implicit) { // if not to generic, they have to match
1871 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1872 werror(E_INCOMPAT_PTYPES);
1879 } else { // to a non pointer
1880 if (IS_PTR(optype)) { // from a pointer
1881 if (implicit) { // sneaky
1882 if (IS_INTEGRAL(type)) {
1883 werror(W_PTR2INTEGRAL_NOCAST);
1885 } else { // shouldn't do that with float, array or structure
1886 werror(E_INCOMPAT_TYPES);
1893 printFromToType (optype, type);
1896 /* if they are the same size create an assignment */
1897 if (getSize (type) == getSize (optype) &&
1898 !IS_BITFIELD (type) &&
1900 !IS_FLOAT (optype) &&
1901 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1902 (!IS_SPEC (type) && !IS_SPEC (optype))))
1905 ic = newiCode ('=', NULL, op);
1906 IC_RESULT (ic) = newiTempOperand (type, 0);
1907 SPIL_LOC (IC_RESULT (ic)) =
1908 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1909 IC_RESULT (ic)->isaddr = 0;
1913 ic = newiCode (CAST, operandFromLink (type),
1914 geniCodeRValue (op, FALSE));
1916 IC_RESULT (ic) = newiTempOperand (type, 0);
1919 /* preserve the storage class & output class */
1920 /* of the original variable */
1921 restype = getSpec (operandType (IC_RESULT (ic)));
1922 if (!IS_LITERAL(opetype))
1923 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1924 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1927 return IC_RESULT (ic);
1930 /*-----------------------------------------------------------------*/
1931 /* geniCodeLabel - will create a Label */
1932 /*-----------------------------------------------------------------*/
1934 geniCodeLabel (symbol * label)
1938 ic = newiCodeLabelGoto (LABEL, label);
1942 /*-----------------------------------------------------------------*/
1943 /* geniCodeGoto - will create a Goto */
1944 /*-----------------------------------------------------------------*/
1946 geniCodeGoto (symbol * label)
1950 ic = newiCodeLabelGoto (GOTO, label);
1954 /*-----------------------------------------------------------------*/
1955 /* geniCodeMultiply - gen intermediate code for multiplication */
1956 /*-----------------------------------------------------------------*/
1958 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1965 /* if they are both literal then we know the result */
1966 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1967 return operandFromValue (valMult (left->operand.valOperand,
1968 right->operand.valOperand));
1970 if (IS_LITERAL(retype)) {
1971 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1974 resType = usualBinaryConversions (&left, &right);
1976 rtype = operandType (right);
1977 retype = getSpec (rtype);
1978 ltype = operandType (left);
1979 letype = getSpec (ltype);
1983 SPEC_NOUN(getSpec(resType))=V_INT;
1986 /* if the right is a literal & power of 2 */
1987 /* then make it a left shift */
1988 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1989 efficient in most cases than 2 bytes result = 2 bytes << literal
1990 if port has 1 byte muldiv */
1991 if (p2 && !IS_FLOAT (letype) &&
1992 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1993 (port->support.muldiv == 1)))
1995 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1997 /* LEFT_OP need same size for left and result, */
1998 left = geniCodeCast (resType, left, TRUE);
1999 ltype = operandType (left);
2001 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2005 ic = newiCode ('*', left, right); /* normal multiplication */
2006 /* if the size left or right > 1 then support routine */
2007 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2011 IC_RESULT (ic) = newiTempOperand (resType, 1);
2014 return IC_RESULT (ic);
2017 /*-----------------------------------------------------------------*/
2018 /* geniCodeDivision - gen intermediate code for division */
2019 /*-----------------------------------------------------------------*/
2021 geniCodeDivision (operand * left, operand * right)
2026 sym_link *rtype = operandType (right);
2027 sym_link *retype = getSpec (rtype);
2028 sym_link *ltype = operandType (left);
2029 sym_link *letype = getSpec (ltype);
2031 resType = usualBinaryConversions (&left, &right);
2033 /* if the right is a literal & power of 2
2034 and left is unsigned then make it a
2036 if (IS_LITERAL (retype) &&
2037 !IS_FLOAT (letype) &&
2038 SPEC_USIGN(letype) &&
2039 (p2 = powof2 ((unsigned long)
2040 floatFromVal (right->operand.valOperand)))) {
2041 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2045 ic = newiCode ('/', left, right); /* normal division */
2046 /* if the size left or right > 1 then support routine */
2047 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2050 IC_RESULT (ic) = newiTempOperand (resType, 0);
2053 return IC_RESULT (ic);
2055 /*-----------------------------------------------------------------*/
2056 /* geniCodeModulus - gen intermediate code for modulus */
2057 /*-----------------------------------------------------------------*/
2059 geniCodeModulus (operand * left, operand * right)
2065 /* if they are both literal then we know the result */
2066 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2067 return operandFromValue (valMod (left->operand.valOperand,
2068 right->operand.valOperand));
2070 resType = usualBinaryConversions (&left, &right);
2072 /* now they are the same size */
2073 ic = newiCode ('%', left, right);
2075 /* if the size left or right > 1 then support routine */
2076 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2078 IC_RESULT (ic) = newiTempOperand (resType, 0);
2081 return IC_RESULT (ic);
2084 /*-----------------------------------------------------------------*/
2085 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2086 /*-----------------------------------------------------------------*/
2088 geniCodePtrPtrSubtract (operand * left, operand * right)
2094 /* if they are both literals then */
2095 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2097 result = operandFromValue (valMinus (left->operand.valOperand,
2098 right->operand.valOperand));
2102 ic = newiCode ('-', left, right);
2104 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2108 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2112 // should we really do this? is this ANSI?
2113 return geniCodeDivision (result,
2114 operandFromLit (getSize (ltype->next)));
2117 /*-----------------------------------------------------------------*/
2118 /* geniCodeSubtract - generates code for subtraction */
2119 /*-----------------------------------------------------------------*/
2121 geniCodeSubtract (operand * left, operand * right)
2128 /* if they both pointers then */
2129 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2130 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2131 return geniCodePtrPtrSubtract (left, right);
2133 /* if they are both literal then we know the result */
2134 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2135 && left->isLiteral && right->isLiteral)
2136 return operandFromValue (valMinus (left->operand.valOperand,
2137 right->operand.valOperand));
2139 /* if left is an array or pointer */
2140 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2142 isarray = left->isaddr;
2143 right = geniCodeMultiply (right,
2144 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2145 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2148 { /* make them the same size */
2149 resType = usualBinaryConversions (&left, &right);
2152 ic = newiCode ('-', left, right);
2154 IC_RESULT (ic) = newiTempOperand (resType, 1);
2155 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2157 /* if left or right is a float */
2158 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2162 return IC_RESULT (ic);
2165 /*-----------------------------------------------------------------*/
2166 /* geniCodeAdd - generates iCode for addition */
2167 /*-----------------------------------------------------------------*/
2169 geniCodeAdd (operand * left, operand * right, int lvl)
2177 /* if the right side is LITERAL zero */
2178 /* return the left side */
2179 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2182 /* if left is literal zero return right */
2183 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2186 /* if left is a pointer then size */
2187 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2189 isarray = left->isaddr;
2190 // there is no need to multiply with 1
2191 if (getSize(ltype->next)!=1) {
2192 size = operandFromLit (getSize (ltype->next));
2193 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2195 resType = copyLinkChain (ltype);
2198 { // make them the same size
2199 resType = usualBinaryConversions (&left, &right);
2202 /* if they are both literals then we know */
2203 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2204 && left->isLiteral && right->isLiteral)
2205 return operandFromValue (valPlus (valFromType (letype),
2206 valFromType (retype)));
2208 ic = newiCode ('+', left, right);
2210 IC_RESULT (ic) = newiTempOperand (resType, 1);
2211 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2213 /* if left or right is a float then support
2215 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2220 return IC_RESULT (ic);
2224 /*-----------------------------------------------------------------*/
2225 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2226 /*-----------------------------------------------------------------*/
2228 aggrToPtr (sym_link * type, bool force)
2233 if (IS_PTR (type) && !force)
2236 etype = getSpec (type);
2237 ptype = newLink (DECLARATOR);
2241 /* set the pointer depending on the storage class */
2242 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2246 /*-----------------------------------------------------------------*/
2247 /* geniCodeArray2Ptr - array to pointer */
2248 /*-----------------------------------------------------------------*/
2250 geniCodeArray2Ptr (operand * op)
2252 sym_link *optype = operandType (op);
2253 sym_link *opetype = getSpec (optype);
2255 /* set the pointer depending on the storage class */
2256 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2263 /*-----------------------------------------------------------------*/
2264 /* geniCodeArray - array access */
2265 /*-----------------------------------------------------------------*/
2267 geniCodeArray (operand * left, operand * right,int lvl)
2270 sym_link *ltype = operandType (left);
2274 if (IS_PTR (ltype->next) && left->isaddr)
2276 left = geniCodeRValue (left, FALSE);
2278 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2281 right = geniCodeMultiply (right,
2282 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2284 /* we can check for limits here */
2285 if (isOperandLiteral (right) &&
2288 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2290 werror (E_ARRAY_BOUND);
2291 right = operandFromLit (0);
2294 ic = newiCode ('+', left, right);
2296 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2297 !IS_AGGREGATE (ltype->next) &&
2298 !IS_PTR (ltype->next))
2299 ? ltype : ltype->next), 0);
2301 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2304 return IC_RESULT (ic);
2307 /*-----------------------------------------------------------------*/
2308 /* geniCodeStruct - generates intermediate code for structres */
2309 /*-----------------------------------------------------------------*/
2311 geniCodeStruct (operand * left, operand * right, bool islval)
2314 sym_link *type = operandType (left);
2315 sym_link *etype = getSpec (type);
2317 symbol *element = getStructElement (SPEC_STRUCT (etype),
2318 right->operand.symOperand);
2320 wassert(IS_SYMOP(right));
2322 /* add the offset */
2323 ic = newiCode ('+', left, operandFromLit (element->offset));
2325 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2327 /* preserve the storage & output class of the struct */
2328 /* as well as the volatile attribute */
2329 retype = getSpec (operandType (IC_RESULT (ic)));
2330 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2331 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2332 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2333 SPEC_CONST (retype) |= SPEC_CONST (etype);
2335 if (IS_PTR (element->type))
2336 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2338 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2341 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2344 /*-----------------------------------------------------------------*/
2345 /* geniCodePostInc - generate int code for Post increment */
2346 /*-----------------------------------------------------------------*/
2348 geniCodePostInc (operand * op)
2352 sym_link *optype = operandType (op);
2354 operand *rv = (IS_ITEMP (op) ?
2355 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2357 sym_link *rvtype = operandType (rv);
2360 /* if this is not an address we have trouble */
2363 werror (E_LVALUE_REQUIRED, "++");
2367 rOp = newiTempOperand (rvtype, 0);
2368 OP_SYMBOL(rOp)->noSpilLoc = 1;
2371 OP_SYMBOL(rv)->noSpilLoc = 1;
2373 geniCodeAssign (rOp, rv, 0);
2375 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2376 if (IS_FLOAT (rvtype))
2377 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2379 ic = newiCode ('+', rv, operandFromLit (size));
2381 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2384 geniCodeAssign (op, result, 0);
2390 /*-----------------------------------------------------------------*/
2391 /* geniCodePreInc - generate code for preIncrement */
2392 /*-----------------------------------------------------------------*/
2394 geniCodePreInc (operand * op, bool lvalue)
2397 sym_link *optype = operandType (op);
2398 operand *rop = (IS_ITEMP (op) ?
2399 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2401 sym_link *roptype = operandType (rop);
2407 werror (E_LVALUE_REQUIRED, "++");
2412 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2413 if (IS_FLOAT (roptype))
2414 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2416 ic = newiCode ('+', rop, operandFromLit (size));
2417 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2420 (void) geniCodeAssign (op, result, 0);
2421 if (lvalue || IS_TRUE_SYMOP (op))
2427 /*-----------------------------------------------------------------*/
2428 /* geniCodePostDec - generates code for Post decrement */
2429 /*-----------------------------------------------------------------*/
2431 geniCodePostDec (operand * op)
2435 sym_link *optype = operandType (op);
2437 operand *rv = (IS_ITEMP (op) ?
2438 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2440 sym_link *rvtype = operandType (rv);
2443 /* if this is not an address we have trouble */
2446 werror (E_LVALUE_REQUIRED, "--");
2450 rOp = newiTempOperand (rvtype, 0);
2451 OP_SYMBOL(rOp)->noSpilLoc = 1;
2454 OP_SYMBOL(rv)->noSpilLoc = 1;
2456 geniCodeAssign (rOp, rv, 0);
2458 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2459 if (IS_FLOAT (rvtype))
2460 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2462 ic = newiCode ('-', rv, operandFromLit (size));
2464 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2467 geniCodeAssign (op, result, 0);
2473 /*-----------------------------------------------------------------*/
2474 /* geniCodePreDec - generate code for pre decrement */
2475 /*-----------------------------------------------------------------*/
2477 geniCodePreDec (operand * op, bool lvalue)
2480 sym_link *optype = operandType (op);
2481 operand *rop = (IS_ITEMP (op) ?
2482 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2484 sym_link *roptype = operandType (rop);
2490 werror (E_LVALUE_REQUIRED, "--");
2495 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2496 if (IS_FLOAT (roptype))
2497 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2499 ic = newiCode ('-', rop, operandFromLit (size));
2500 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2503 (void) geniCodeAssign (op, result, 0);
2504 if (lvalue || IS_TRUE_SYMOP (op))
2511 /*-----------------------------------------------------------------*/
2512 /* geniCodeBitwise - gen int code for bitWise operators */
2513 /*-----------------------------------------------------------------*/
2515 geniCodeBitwise (operand * left, operand * right,
2516 int oper, sym_link * resType)
2520 left = geniCodeCast (resType, left, TRUE);
2521 right = geniCodeCast (resType, right, TRUE);
2523 ic = newiCode (oper, left, right);
2524 IC_RESULT (ic) = newiTempOperand (resType, 0);
2527 return IC_RESULT (ic);
2530 /*-----------------------------------------------------------------*/
2531 /* geniCodeAddressOf - gens icode for '&' address of operator */
2532 /*-----------------------------------------------------------------*/
2534 geniCodeAddressOf (operand * op)
2538 sym_link *optype = operandType (op);
2539 sym_link *opetype = getSpec (optype);
2541 /* lvalue check already done in decorateType */
2542 /* this must be a lvalue */
2543 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2544 /* werror (E_LVALUE_REQUIRED,"&"); */
2548 p = newLink (DECLARATOR);
2550 /* set the pointer depending on the storage class */
2551 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2553 p->next = copyLinkChain (optype);
2555 /* if already a temp */
2558 setOperandType (op, p);
2563 /* other wise make this of the type coming in */
2564 ic = newiCode (ADDRESS_OF, op, NULL);
2565 IC_RESULT (ic) = newiTempOperand (p, 1);
2566 IC_RESULT (ic)->isaddr = 0;
2568 return IC_RESULT (ic);
2570 /*-----------------------------------------------------------------*/
2571 /* setOClass - sets the output class depending on the pointer type */
2572 /*-----------------------------------------------------------------*/
2574 setOClass (sym_link * ptr, sym_link * spec)
2576 switch (DCL_TYPE (ptr))
2579 SPEC_OCLS (spec) = data;
2583 SPEC_OCLS (spec) = generic;
2587 SPEC_OCLS (spec) = xdata;
2591 SPEC_OCLS (spec) = code;
2595 SPEC_OCLS (spec) = idata;
2599 SPEC_OCLS (spec) = xstack;
2603 SPEC_OCLS (spec) = eeprom;
2612 /*-----------------------------------------------------------------*/
2613 /* geniCodeDerefPtr - dereference pointer with '*' */
2614 /*-----------------------------------------------------------------*/
2616 geniCodeDerefPtr (operand * op,int lvl)
2618 sym_link *rtype, *retype;
2619 sym_link *optype = operandType (op);
2621 // if this is an array then array access
2622 if (IS_ARRAY (optype)) {
2623 // don't worry, this will be optimized out later
2624 return geniCodeArray (op, operandFromLit (0), lvl);
2627 // just in case someone screws up
2628 wassert (IS_PTR (optype));
2630 if (IS_TRUE_SYMOP (op))
2633 op = geniCodeRValue (op, TRUE);
2636 /* now get rid of the pointer part */
2637 if (isLvaluereq(lvl) && IS_ITEMP (op))
2639 retype = getSpec (rtype = copyLinkChain (optype));
2643 retype = getSpec (rtype = copyLinkChain (optype->next));
2644 /* outputclass needs 2b updated */
2645 setOClass (optype, retype);
2648 op->isGptr = IS_GENPTR (optype);
2650 op->isaddr = (IS_PTR (rtype) ||
2651 IS_STRUCT (rtype) ||
2656 if (!isLvaluereq(lvl))
2657 op = geniCodeRValue (op, TRUE);
2659 setOperandType (op, rtype);
2664 /*-----------------------------------------------------------------*/
2665 /* geniCodeUnaryMinus - does a unary minus of the operand */
2666 /*-----------------------------------------------------------------*/
2668 geniCodeUnaryMinus (operand * op)
2671 sym_link *optype = operandType (op);
2673 if (IS_LITERAL (optype))
2674 return operandFromLit (-floatFromVal (op->operand.valOperand));
2676 ic = newiCode (UNARYMINUS, op, NULL);
2677 IC_RESULT (ic) = newiTempOperand (optype, 0);
2679 return IC_RESULT (ic);
2682 /*-----------------------------------------------------------------*/
2683 /* geniCodeLeftShift - gen i code for left shift */
2684 /*-----------------------------------------------------------------*/
2686 geniCodeLeftShift (operand * left, operand * right)
2690 ic = newiCode (LEFT_OP, left, right);
2691 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2693 return IC_RESULT (ic);
2696 /*-----------------------------------------------------------------*/
2697 /* geniCodeRightShift - gen i code for right shift */
2698 /*-----------------------------------------------------------------*/
2700 geniCodeRightShift (operand * left, operand * right)
2704 ic = newiCode (RIGHT_OP, left, right);
2705 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2707 return IC_RESULT (ic);
2710 /*-----------------------------------------------------------------*/
2711 /* geniCodeLogic- logic code */
2712 /*-----------------------------------------------------------------*/
2714 geniCodeLogic (operand * left, operand * right, int op)
2718 sym_link *rtype = operandType (right);
2719 sym_link *ltype = operandType (left);
2721 /* left is integral type and right is literal then
2722 check if the literal value is within bounds */
2723 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2725 checkConstantRange(ltype,
2726 OP_VALUE(right), "compare operation", 1);
2729 /* if one operand is a pointer and the other is a literal generic void pointer,
2730 change the type of the literal generic void pointer to match the other pointer */
2731 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2732 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2734 /* find left's definition */
2735 ic = (iCode *) setFirstItem (iCodeChain);
2738 if (((ic->op == CAST) || (ic->op == '='))
2739 && isOperandEqual(left, IC_RESULT (ic)))
2742 ic = setNextItem (iCodeChain);
2744 /* if casting literal to generic pointer, then cast to rtype instead */
2745 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2747 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2748 ltype = operandType(left);
2751 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2752 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2754 /* find right's definition */
2755 ic = (iCode *) setFirstItem (iCodeChain);
2758 if (((ic->op == CAST) || (ic->op == '='))
2759 && isOperandEqual(right, IC_RESULT (ic)))
2762 ic = setNextItem (iCodeChain);
2764 /* if casting literal to generic pointer, then cast to rtype instead */
2765 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2767 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2768 rtype = operandType(right);
2772 ctype = usualBinaryConversions (&left, &right);
2774 ic = newiCode (op, left, right);
2775 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2777 /* if comparing float
2778 and not a '==' || '!=' || '&&' || '||' (these
2780 if (IS_FLOAT(ctype) &&
2788 return IC_RESULT (ic);
2791 /*-----------------------------------------------------------------*/
2792 /* geniCodeUnary - for a a generic unary operation */
2793 /*-----------------------------------------------------------------*/
2795 geniCodeUnary (operand * op, int oper)
2797 iCode *ic = newiCode (oper, op, NULL);
2799 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2801 return IC_RESULT (ic);
2804 /*-----------------------------------------------------------------*/
2805 /* geniCodeConditional - geniCode for '?' ':' operation */
2806 /*-----------------------------------------------------------------*/
2808 geniCodeConditional (ast * tree,int lvl)
2811 symbol *falseLabel = newiTempLabel (NULL);
2812 symbol *exitLabel = newiTempLabel (NULL);
2813 operand *cond = ast2iCode (tree->left,lvl+1);
2814 operand *true, *false, *result;
2816 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2820 true = ast2iCode (tree->right->left,lvl+1);
2822 /* move the value to a new Operand */
2823 result = newiTempOperand (tree->right->ftype, 0);
2824 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2826 /* generate an unconditional goto */
2827 geniCodeGoto (exitLabel);
2829 /* now for the right side */
2830 geniCodeLabel (falseLabel);
2832 false = ast2iCode (tree->right->right,lvl+1);
2833 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2835 /* create the exit label */
2836 geniCodeLabel (exitLabel);
2841 /*-----------------------------------------------------------------*/
2842 /* geniCodeAssign - generate code for assignment */
2843 /*-----------------------------------------------------------------*/
2845 geniCodeAssign (operand * left, operand * right, int nosupdate)
2848 sym_link *ltype = operandType (left);
2849 sym_link *rtype = operandType (right);
2851 if (!left->isaddr && !IS_ITEMP (left))
2853 werror (E_LVALUE_REQUIRED, "assignment");
2857 /* left is integral type and right is literal then
2858 check if the literal value is within bounds */
2859 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2861 checkConstantRange(ltype,
2862 OP_VALUE(right), "= operation", 0);
2865 /* if the left & right type don't exactly match */
2866 /* if pointer set then make sure the check is
2867 done with the type & not the pointer */
2868 /* then cast rights type to left */
2870 /* first check the type for pointer assignement */
2871 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2872 compareType (ltype, rtype) <= 0)
2874 if (compareType (ltype->next, rtype) < 0)
2875 right = geniCodeCast (ltype->next, right, TRUE);
2877 else if (compareType (ltype, rtype) < 0)
2878 right = geniCodeCast (ltype, right, TRUE);
2880 /* If left is a true symbol & ! volatile
2881 create an assignment to temporary for
2882 the right & then assign this temporary
2883 to the symbol. This is SSA (static single
2884 assignment). Isn't it simple and folks have
2885 published mountains of paper on it */
2886 if (IS_TRUE_SYMOP (left) &&
2887 !isOperandVolatile (left, FALSE) &&
2888 isOperandGlobal (left))
2892 if (IS_TRUE_SYMOP (right))
2893 sym = OP_SYMBOL (right);
2894 ic = newiCode ('=', NULL, right);
2895 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2896 SPIL_LOC (right) = sym;
2900 ic = newiCode ('=', NULL, right);
2901 IC_RESULT (ic) = left;
2904 /* if left isgptr flag is set then support
2905 routine will be required */
2909 ic->nosupdate = nosupdate;
2913 /*-----------------------------------------------------------------*/
2914 /* geniCodeDummyRead - generate code for dummy read */
2915 /*-----------------------------------------------------------------*/
2917 geniCodeDummyRead (operand * op)
2920 sym_link *type = operandType (op);
2922 if (!IS_VOLATILE(type))
2925 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2931 /*-----------------------------------------------------------------*/
2932 /* geniCodeSEParms - generate code for side effecting fcalls */
2933 /*-----------------------------------------------------------------*/
2935 geniCodeSEParms (ast * parms,int lvl)
2940 if (parms->type == EX_OP && parms->opval.op == PARAM)
2942 geniCodeSEParms (parms->left,lvl);
2943 geniCodeSEParms (parms->right,lvl);
2947 /* hack don't like this but too lazy to think of
2949 if (IS_ADDRESS_OF_OP (parms))
2950 parms->left->lvalue = 1;
2952 if (IS_CAST_OP (parms) &&
2953 IS_PTR (parms->ftype) &&
2954 IS_ADDRESS_OF_OP (parms->right))
2955 parms->right->left->lvalue = 1;
2957 parms->opval.oprnd =
2958 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2960 parms->type = EX_OPERAND;
2961 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2962 SPEC_ARGREG(parms->ftype);
2965 /*-----------------------------------------------------------------*/
2966 /* geniCodeParms - generates parameters */
2967 /*-----------------------------------------------------------------*/
2969 geniCodeParms (ast * parms, value *argVals, int *stack,
2970 sym_link * fetype, symbol * func,int lvl)
2978 if (argVals==NULL) {
2980 argVals=FUNC_ARGS(func->type);
2983 /* if this is a param node then do the left & right */
2984 if (parms->type == EX_OP && parms->opval.op == PARAM)
2986 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2987 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2991 /* get the parameter value */
2992 if (parms->type == EX_OPERAND)
2993 pval = parms->opval.oprnd;
2996 /* maybe this else should go away ?? */
2997 /* hack don't like this but too lazy to think of
2999 if (IS_ADDRESS_OF_OP (parms))
3000 parms->left->lvalue = 1;
3002 if (IS_CAST_OP (parms) &&
3003 IS_PTR (parms->ftype) &&
3004 IS_ADDRESS_OF_OP (parms->right))
3005 parms->right->left->lvalue = 1;
3007 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3010 /* if register parm then make it a send */
3011 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3012 IFFUNC_ISBUILTIN(func->type))
3014 ic = newiCode (SEND, pval, NULL);
3015 ic->argreg = SPEC_ARGREG(parms->etype);
3016 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3021 /* now decide whether to push or assign */
3022 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3026 operand *top = operandFromSymbol (argVals->sym);
3027 /* clear useDef and other bitVectors */
3028 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3029 geniCodeAssign (top, pval, 1);
3033 sym_link *p = operandType (pval);
3035 ic = newiCode (IPUSH, pval, NULL);
3037 /* update the stack adjustment */
3038 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3043 argVals=argVals->next;
3047 /*-----------------------------------------------------------------*/
3048 /* geniCodeCall - generates temp code for calling */
3049 /*-----------------------------------------------------------------*/
3051 geniCodeCall (operand * left, ast * parms,int lvl)
3055 sym_link *type, *etype;
3058 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3059 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3060 werror (E_FUNCTION_EXPECTED);
3064 /* take care of parameters with side-effecting
3065 function calls in them, this is required to take care
3066 of overlaying function parameters */
3067 geniCodeSEParms (parms,lvl);
3069 /* first the parameters */
3070 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3072 /* now call : if symbol then pcall */
3073 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3074 ic = newiCode (PCALL, left, NULL);
3076 ic = newiCode (CALL, left, NULL);
3079 type = copyLinkChain (operandType (left)->next);
3080 etype = getSpec (type);
3081 SPEC_EXTR (etype) = 0;
3082 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3086 /* stack adjustment after call */
3087 ic->parmBytes = stack;
3092 /*-----------------------------------------------------------------*/
3093 /* geniCodeReceive - generate intermediate code for "receive" */
3094 /*-----------------------------------------------------------------*/
3096 geniCodeReceive (value * args)
3098 /* for all arguments that are passed in registers */
3102 if (IS_REGPARM (args->etype))
3104 operand *opr = operandFromValue (args);
3106 symbol *sym = OP_SYMBOL (opr);
3109 /* we will use it after all optimizations
3110 and before liveRange calculation */
3111 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3114 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3115 options.stackAuto == 0 &&
3116 (!(options.model == MODEL_FLAT24)) )
3121 opl = newiTempOperand (args->type, 0);
3123 sym->reqv->key = sym->key;
3124 OP_SYMBOL (sym->reqv)->key = sym->key;
3125 OP_SYMBOL (sym->reqv)->isreqv = 1;
3126 OP_SYMBOL (sym->reqv)->islocal = 0;
3127 SPIL_LOC (sym->reqv) = sym;
3131 ic = newiCode (RECEIVE, NULL, NULL);
3132 ic->argreg = SPEC_ARGREG(args->etype);
3134 currFunc->recvSize = getSize (sym->type);
3137 IC_RESULT (ic) = opr;
3145 /*-----------------------------------------------------------------*/
3146 /* geniCodeFunctionBody - create the function body */
3147 /*-----------------------------------------------------------------*/
3149 geniCodeFunctionBody (ast * tree,int lvl)
3156 /* reset the auto generation */
3162 func = ast2iCode (tree->left,lvl+1);
3163 fetype = getSpec (operandType (func));
3165 savelineno = lineno;
3166 lineno = OP_SYMBOL (func)->lineDef;
3167 /* create an entry label */
3168 geniCodeLabel (entryLabel);
3169 lineno = savelineno;
3171 /* create a proc icode */
3172 ic = newiCode (FUNCTION, func, NULL);
3173 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3177 /* for all parameters that are passed
3178 on registers add a "receive" */
3179 geniCodeReceive (tree->values.args);
3181 /* generate code for the body */
3182 ast2iCode (tree->right,lvl+1);
3184 /* create a label for return */
3185 geniCodeLabel (returnLabel);
3187 /* now generate the end proc */
3188 ic = newiCode (ENDFUNCTION, func, NULL);
3193 /*-----------------------------------------------------------------*/
3194 /* geniCodeReturn - gen icode for 'return' statement */
3195 /*-----------------------------------------------------------------*/
3197 geniCodeReturn (operand * op)
3201 /* if the operand is present force an rvalue */
3203 op = geniCodeRValue (op, FALSE);
3205 ic = newiCode (RETURN, op, NULL);
3209 /*-----------------------------------------------------------------*/
3210 /* geniCodeIfx - generates code for extended if statement */
3211 /*-----------------------------------------------------------------*/
3213 geniCodeIfx (ast * tree,int lvl)
3216 operand *condition = ast2iCode (tree->left,lvl+1);
3219 /* if condition is null then exit */
3223 condition = geniCodeRValue (condition, FALSE);
3225 cetype = getSpec (operandType (condition));
3226 /* if the condition is a literal */
3227 if (IS_LITERAL (cetype))
3229 if (floatFromVal (condition->operand.valOperand))
3231 if (tree->trueLabel)
3232 geniCodeGoto (tree->trueLabel);
3238 if (tree->falseLabel)
3239 geniCodeGoto (tree->falseLabel);
3246 if (tree->trueLabel)
3248 ic = newiCodeCondition (condition,
3253 if (tree->falseLabel)
3254 geniCodeGoto (tree->falseLabel);
3258 ic = newiCodeCondition (condition,
3265 ast2iCode (tree->right,lvl+1);
3268 /*-----------------------------------------------------------------*/
3269 /* geniCodeJumpTable - tries to create a jump table for switch */
3270 /*-----------------------------------------------------------------*/
3272 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3274 int min = 0, max = 0, t, cnt = 0;
3280 int needRangeCheck = !optimize.noJTabBoundary
3281 || tree->values.switchVals.swDefault;
3283 if (!tree || !caseVals)
3286 /* the criteria for creating a jump table is */
3287 /* all integer numbers between the maximum & minimum must */
3288 /* be present , the maximum value should not exceed 255 */
3289 min = max = (int) floatFromVal (vch = caseVals);
3290 SNPRINTF (buffer, sizeof(buffer),
3292 tree->values.switchVals.swNum,
3294 addSet (&labels, newiTempLabel (buffer));
3296 /* if there is only one case value then no need */
3297 if (!(vch = vch->next))
3302 if (((t = (int) floatFromVal (vch)) - max) != 1)
3304 SNPRINTF (buffer, sizeof(buffer),
3306 tree->values.switchVals.swNum,
3308 addSet (&labels, newiTempLabel (buffer));
3314 /* if the number of case statements <= 2 then */
3315 /* it is not economical to create the jump table */
3316 /* since two compares are needed for boundary conditions */
3317 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3320 if (tree->values.switchVals.swDefault)
3322 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3326 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3330 falseLabel = newiTempLabel (buffer);
3332 /* so we can create a jumptable */
3333 /* first we rule out the boundary conditions */
3334 /* if only optimization says so */
3337 sym_link *cetype = getSpec (operandType (cond));
3338 /* no need to check the lower bound if
3339 the condition is unsigned & minimum value is zero */
3340 if (!(min == 0 && SPEC_USIGN (cetype)))
3342 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3343 ic = newiCodeCondition (boundary, falseLabel, NULL);
3347 /* now for upper bounds */
3348 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3349 ic = newiCodeCondition (boundary, falseLabel, NULL);
3353 /* if the min is not zero then we no make it zero */
3356 cond = geniCodeSubtract (cond, operandFromLit (min));
3357 if (!IS_LITERAL(getSpec(operandType(cond))))
3358 setOperandType (cond, UCHARTYPE);
3361 /* now create the jumptable */
3362 ic = newiCode (JUMPTABLE, NULL, NULL);
3363 IC_JTCOND (ic) = cond;
3364 IC_JTLABELS (ic) = labels;
3369 /*-----------------------------------------------------------------*/
3370 /* geniCodeSwitch - changes a switch to a if statement */
3371 /*-----------------------------------------------------------------*/
3373 geniCodeSwitch (ast * tree,int lvl)
3376 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3377 value *caseVals = tree->values.switchVals.swVals;
3378 symbol *trueLabel, *falseLabel;
3380 /* If the condition is a literal, then just jump to the */
3381 /* appropriate case label. */
3382 if (IS_LITERAL(getSpec(operandType(cond))))
3384 int switchVal, caseVal;
3386 switchVal = (int) floatFromVal (cond->operand.valOperand);
3389 caseVal = (int) floatFromVal (caseVals);
3390 if (caseVal == switchVal)
3392 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3393 tree->values.switchVals.swNum, caseVal);
3394 trueLabel = newiTempLabel (buffer);
3395 geniCodeGoto (trueLabel);
3398 caseVals = caseVals->next;
3400 goto defaultOrBreak;
3403 /* if we can make this a jump table */
3404 if (geniCodeJumpTable (cond, caseVals, tree))
3405 goto jumpTable; /* no need for the comparison */
3407 /* for the cases defined do */
3411 operand *compare = geniCodeLogic (cond,
3412 operandFromValue (caseVals),
3415 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3416 tree->values.switchVals.swNum,
3417 (int) floatFromVal (caseVals));
3418 trueLabel = newiTempLabel (buffer);
3420 ic = newiCodeCondition (compare, trueLabel, NULL);
3422 caseVals = caseVals->next;
3427 /* if default is present then goto break else break */
3428 if (tree->values.switchVals.swDefault)
3430 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3434 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3437 falseLabel = newiTempLabel (buffer);
3438 geniCodeGoto (falseLabel);
3441 ast2iCode (tree->right,lvl+1);
3444 /*-----------------------------------------------------------------*/
3445 /* geniCodeInline - intermediate code for inline assembler */
3446 /*-----------------------------------------------------------------*/
3448 geniCodeInline (ast * tree)
3452 ic = newiCode (INLINEASM, NULL, NULL);
3453 IC_INLINE (ic) = tree->values.inlineasm;
3457 /*-----------------------------------------------------------------*/
3458 /* geniCodeArrayInit - intermediate code for array initializer */
3459 /*-----------------------------------------------------------------*/
3461 geniCodeArrayInit (ast * tree, operand *array)
3465 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3466 ic = newiCode (ARRAYINIT, array, NULL);
3467 IC_ARRAYILIST (ic) = tree->values.constlist;
3469 operand *left=newOperand(), *right=newOperand();
3470 left->type=right->type=SYMBOL;
3471 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3472 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3473 ic = newiCode (ARRAYINIT, left, right);
3478 /*-----------------------------------------------------------------*/
3479 /* geniCodeCritical - intermediate code for a critical statement */
3480 /*-----------------------------------------------------------------*/
3482 geniCodeCritical (ast *tree, int lvl)
3487 /* If op is NULL, the original interrupt state will saved on */
3488 /* the stack. Otherwise, it will be saved in op. */
3490 /* Generate a save of the current interrupt state & disabled */
3491 ic = newiCode (CRITICAL, NULL, NULL);
3492 IC_RESULT (ic) = op;
3495 /* Generate the critical code sequence */
3496 if (tree->left && tree->left->type == EX_VALUE)
3497 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3499 ast2iCode (tree->left,lvl+1);
3501 /* Generate a restore of the original interrupt state */
3502 ic = newiCode (ENDCRITICAL, NULL, op);
3506 /*-----------------------------------------------------------------*/
3507 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3508 /* particular case. Ie : assigning or dereferencing array or ptr */
3509 /*-----------------------------------------------------------------*/
3510 set * lvaluereqSet = NULL;
3511 typedef struct lvalItem
3518 /*-----------------------------------------------------------------*/
3519 /* addLvaluereq - add a flag for lvalreq for current ast level */
3520 /*-----------------------------------------------------------------*/
3521 void addLvaluereq(int lvl)
3523 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3526 addSetHead(&lvaluereqSet,lpItem);
3529 /*-----------------------------------------------------------------*/
3530 /* delLvaluereq - del a flag for lvalreq for current ast level */
3531 /*-----------------------------------------------------------------*/
3535 lpItem = getSet(&lvaluereqSet);
3536 if(lpItem) Safe_free(lpItem);
3538 /*-----------------------------------------------------------------*/
3539 /* clearLvaluereq - clear lvalreq flag */
3540 /*-----------------------------------------------------------------*/
3541 void clearLvaluereq()
3544 lpItem = peekSet(lvaluereqSet);
3545 if(lpItem) lpItem->req = 0;
3547 /*-----------------------------------------------------------------*/
3548 /* getLvaluereq - get the last lvalreq level */
3549 /*-----------------------------------------------------------------*/
3550 int getLvaluereqLvl()
3553 lpItem = peekSet(lvaluereqSet);
3554 if(lpItem) return lpItem->lvl;
3557 /*-----------------------------------------------------------------*/
3558 /* isLvaluereq - is lvalreq valid for this level ? */
3559 /*-----------------------------------------------------------------*/
3560 int isLvaluereq(int lvl)
3563 lpItem = peekSet(lvaluereqSet);
3564 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3568 /*-----------------------------------------------------------------*/
3569 /* ast2iCode - creates an icodeList from an ast */
3570 /*-----------------------------------------------------------------*/
3572 ast2iCode (ast * tree,int lvl)
3574 operand *left = NULL;
3575 operand *right = NULL;
3579 /* set the global variables for filename & line number */
3581 filename = tree->filename;
3583 lineno = tree->lineno;
3585 block = tree->block;
3587 scopeLevel = tree->level;
3589 if (tree->type == EX_VALUE)
3590 return operandFromValue (tree->opval.val);
3592 if (tree->type == EX_LINK)
3593 return operandFromLink (tree->opval.lnk);
3595 /* if we find a nullop */
3596 if (tree->type == EX_OP &&
3597 (tree->opval.op == NULLOP ||
3598 tree->opval.op == BLOCK))
3600 if (tree->left && tree->left->type == EX_VALUE)
3601 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3603 ast2iCode (tree->left,lvl+1);
3604 if (tree->right && tree->right->type == EX_VALUE)
3605 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3607 ast2iCode (tree->right,lvl+1);
3611 /* special cases for not evaluating */
3612 if (tree->opval.op != ':' &&
3613 tree->opval.op != '?' &&
3614 tree->opval.op != CALL &&
3615 tree->opval.op != IFX &&
3616 tree->opval.op != LABEL &&
3617 tree->opval.op != GOTO &&
3618 tree->opval.op != SWITCH &&
3619 tree->opval.op != FUNCTION &&
3620 tree->opval.op != INLINEASM &&
3621 tree->opval.op != CRITICAL)
3624 if (IS_ASSIGN_OP (tree->opval.op) ||
3625 IS_DEREF_OP (tree) ||
3626 (tree->opval.op == '&' && !tree->right) ||
3627 tree->opval.op == PTR_OP)
3630 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3631 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3634 left = operandFromAst (tree->left,lvl);
3636 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3637 left = geniCodeRValue (left, TRUE);
3641 left = operandFromAst (tree->left,lvl);
3643 if (tree->opval.op == INC_OP ||
3644 tree->opval.op == DEC_OP)
3647 right = operandFromAst (tree->right,lvl);
3652 right = operandFromAst (tree->right,lvl);
3656 /* now depending on the type of operand */
3657 /* this will be a biggy */
3658 switch (tree->opval.op)
3661 case '[': /* array operation */
3663 //sym_link *ltype = operandType (left);
3664 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3665 left = geniCodeRValue (left, FALSE);
3666 right = geniCodeRValue (right, TRUE);
3669 return geniCodeArray (left, right,lvl);
3671 case '.': /* structure dereference */
3672 if (IS_PTR (operandType (left)))
3673 left = geniCodeRValue (left, TRUE);
3675 left = geniCodeRValue (left, FALSE);
3677 return geniCodeStruct (left, right, tree->lvalue);
3679 case PTR_OP: /* structure pointer dereference */
3682 pType = operandType (left);
3683 left = geniCodeRValue (left, TRUE);
3685 setOClass (pType, getSpec (operandType (left)));
3688 return geniCodeStruct (left, right, tree->lvalue);
3690 case INC_OP: /* increment operator */
3692 return geniCodePostInc (left);
3694 return geniCodePreInc (right, tree->lvalue);
3696 case DEC_OP: /* decrement operator */
3698 return geniCodePostDec (left);
3700 return geniCodePreDec (right, tree->lvalue);
3702 case '&': /* bitwise and or address of operator */
3704 { /* this is a bitwise operator */
3705 left = geniCodeRValue (left, FALSE);
3706 right = geniCodeRValue (right, FALSE);
3707 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3710 return geniCodeAddressOf (left);
3712 case '|': /* bitwise or & xor */
3714 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3715 geniCodeRValue (right, FALSE),
3720 return geniCodeDivision (geniCodeRValue (left, FALSE),
3721 geniCodeRValue (right, FALSE));
3724 return geniCodeModulus (geniCodeRValue (left, FALSE),
3725 geniCodeRValue (right, FALSE));
3728 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3729 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3731 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3735 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3736 geniCodeRValue (right, FALSE));
3738 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3742 return geniCodeAdd (geniCodeRValue (left, FALSE),
3743 geniCodeRValue (right, FALSE),lvl);
3745 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3748 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3749 geniCodeRValue (right, FALSE));
3752 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3753 geniCodeRValue (right, FALSE));
3755 #if 0 // this indeed needs a second thought
3759 // let's keep this simple: get the rvalue we need
3760 op=geniCodeRValue (right, FALSE);
3761 // now cast it to whatever we want
3762 op=geniCodeCast (operandType(left), op, FALSE);
3763 // if this is going to be used as an lvalue, make it so
3769 #else // bug #604575, is it a bug ????
3770 return geniCodeCast (operandType (left),
3771 geniCodeRValue (right, FALSE), FALSE);
3778 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3783 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3784 setOperandType (op, UCHARTYPE);
3795 /* different compilers (even different gccs) evaluate
3796 the two calls in a different order. to get the same
3797 result on all machines we've to specify a clear sequence.
3798 return geniCodeLogic (geniCodeRValue (left, FALSE),
3799 geniCodeRValue (right, FALSE),
3803 operand *leftOp, *rightOp;
3805 rightOp = geniCodeRValue (right, FALSE);
3806 leftOp = geniCodeRValue (left , FALSE);
3808 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3811 return geniCodeConditional (tree,lvl);
3814 return operandFromLit (getSize (tree->right->ftype));
3818 sym_link *rtype = operandType (right);
3819 sym_link *ltype = operandType (left);
3820 if (IS_PTR (rtype) && IS_ITEMP (right)
3821 && right->isaddr && compareType (rtype->next, ltype) == 1)
3822 right = geniCodeRValue (right, TRUE);
3824 right = geniCodeRValue (right, FALSE);
3826 geniCodeAssign (left, right, 0);
3831 geniCodeAssign (left,
3832 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3834 geniCodeRValue (right, FALSE),FALSE), 0);
3838 geniCodeAssign (left,
3839 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3841 geniCodeRValue (right, FALSE)), 0);
3844 geniCodeAssign (left,
3845 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3847 geniCodeRValue (right, FALSE)), 0);
3850 sym_link *rtype = operandType (right);
3851 sym_link *ltype = operandType (left);
3852 if (IS_PTR (rtype) && IS_ITEMP (right)
3853 && right->isaddr && compareType (rtype->next, ltype) == 1)
3854 right = geniCodeRValue (right, TRUE);
3856 right = geniCodeRValue (right, FALSE);
3859 return geniCodeAssign (left,
3860 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3866 sym_link *rtype = operandType (right);
3867 sym_link *ltype = operandType (left);
3868 if (IS_PTR (rtype) && IS_ITEMP (right)
3869 && right->isaddr && compareType (rtype->next, ltype) == 1)
3871 right = geniCodeRValue (right, TRUE);
3875 right = geniCodeRValue (right, FALSE);
3878 geniCodeAssign (left,
3879 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3885 geniCodeAssign (left,
3886 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3888 geniCodeRValue (right, FALSE)), 0);
3891 geniCodeAssign (left,
3892 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3894 geniCodeRValue (right, FALSE)), 0);
3897 geniCodeAssign (left,
3898 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3900 geniCodeRValue (right, FALSE),
3902 operandType (left)), 0);
3905 geniCodeAssign (left,
3906 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3908 geniCodeRValue (right, FALSE),
3910 operandType (left)), 0);
3913 geniCodeAssign (left,
3914 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3916 geniCodeRValue (right, FALSE),
3918 operandType (left)), 0);
3920 return geniCodeRValue (right, FALSE);
3923 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3926 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3927 return ast2iCode (tree->right,lvl+1);
3930 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3931 return ast2iCode (tree->right,lvl+1);
3934 geniCodeFunctionBody (tree,lvl);
3938 geniCodeReturn (right);
3942 geniCodeIfx (tree,lvl);
3946 geniCodeSwitch (tree,lvl);
3950 geniCodeInline (tree);
3954 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3958 geniCodeCritical (tree, lvl);
3964 /*-----------------------------------------------------------------*/
3965 /* reverseICChain - gets from the list and creates a linkedlist */
3966 /*-----------------------------------------------------------------*/
3973 while ((loop = getSet (&iCodeChain)))
3985 /*-----------------------------------------------------------------*/
3986 /* iCodeFromAst - given an ast will convert it to iCode */
3987 /*-----------------------------------------------------------------*/
3989 iCodeFromAst (ast * tree)
3991 returnLabel = newiTempLabel ("_return");
3992 entryLabel = newiTempLabel ("_entry");
3994 return reverseiCChain ();
3997 static const char *opTypeToStr(OPTYPE op)
4001 case SYMBOL: return "symbol";
4002 case VALUE: return "value";
4003 case TYPE: return "type";
4005 return "undefined type";
4009 operand *validateOpType(operand *op,
4016 if (op && op->type == type)
4021 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4022 " expected %s, got %s\n",
4023 macro, args, file, line,
4024 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4026 return op; // never reached, makes compiler happy.