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 (rtype)))
2182 /* if left is literal zero return right */
2183 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
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 (ltype),
2206 valFromType (rtype)));
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);
2279 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2282 right = geniCodeMultiply (right,
2283 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2285 /* we can check for limits here */
2286 if (isOperandLiteral (right) &&
2289 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2291 werror (E_ARRAY_BOUND);
2292 right = operandFromLit (0);
2295 ic = newiCode ('+', left, right);
2297 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2298 !IS_AGGREGATE (ltype->next) &&
2299 !IS_PTR (ltype->next))
2300 ? ltype : ltype->next), 0);
2302 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2305 return IC_RESULT (ic);
2308 /*-----------------------------------------------------------------*/
2309 /* geniCodeStruct - generates intermediate code for structres */
2310 /*-----------------------------------------------------------------*/
2312 geniCodeStruct (operand * left, operand * right, bool islval)
2315 sym_link *type = operandType (left);
2316 sym_link *etype = getSpec (type);
2318 symbol *element = getStructElement (SPEC_STRUCT (etype),
2319 right->operand.symOperand);
2321 wassert(IS_SYMOP(right));
2323 /* add the offset */
2324 ic = newiCode ('+', left, operandFromLit (element->offset));
2326 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2328 /* preserve the storage & output class of the struct */
2329 /* as well as the volatile attribute */
2330 retype = getSpec (operandType (IC_RESULT (ic)));
2331 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2332 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2333 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2334 SPEC_CONST (retype) |= SPEC_CONST (etype);
2336 if (IS_PTR (element->type))
2337 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2339 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2342 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2345 /*-----------------------------------------------------------------*/
2346 /* geniCodePostInc - generate int code for Post increment */
2347 /*-----------------------------------------------------------------*/
2349 geniCodePostInc (operand * op)
2353 sym_link *optype = operandType (op);
2355 operand *rv = (IS_ITEMP (op) ?
2356 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2358 sym_link *rvtype = operandType (rv);
2361 /* if this is not an address we have trouble */
2364 werror (E_LVALUE_REQUIRED, "++");
2368 rOp = newiTempOperand (rvtype, 0);
2369 OP_SYMBOL(rOp)->noSpilLoc = 1;
2372 OP_SYMBOL(rv)->noSpilLoc = 1;
2374 geniCodeAssign (rOp, rv, 0);
2376 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2377 if (IS_FLOAT (rvtype))
2378 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2380 ic = newiCode ('+', rv, operandFromLit (size));
2382 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2385 geniCodeAssign (op, result, 0);
2391 /*-----------------------------------------------------------------*/
2392 /* geniCodePreInc - generate code for preIncrement */
2393 /*-----------------------------------------------------------------*/
2395 geniCodePreInc (operand * op, bool lvalue)
2398 sym_link *optype = operandType (op);
2399 operand *rop = (IS_ITEMP (op) ?
2400 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2402 sym_link *roptype = operandType (rop);
2408 werror (E_LVALUE_REQUIRED, "++");
2413 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2414 if (IS_FLOAT (roptype))
2415 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2417 ic = newiCode ('+', rop, operandFromLit (size));
2418 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2421 (void) geniCodeAssign (op, result, 0);
2422 if (lvalue || IS_TRUE_SYMOP (op))
2428 /*-----------------------------------------------------------------*/
2429 /* geniCodePostDec - generates code for Post decrement */
2430 /*-----------------------------------------------------------------*/
2432 geniCodePostDec (operand * op)
2436 sym_link *optype = operandType (op);
2438 operand *rv = (IS_ITEMP (op) ?
2439 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2441 sym_link *rvtype = operandType (rv);
2444 /* if this is not an address we have trouble */
2447 werror (E_LVALUE_REQUIRED, "--");
2451 rOp = newiTempOperand (rvtype, 0);
2452 OP_SYMBOL(rOp)->noSpilLoc = 1;
2455 OP_SYMBOL(rv)->noSpilLoc = 1;
2457 geniCodeAssign (rOp, rv, 0);
2459 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2460 if (IS_FLOAT (rvtype))
2461 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2463 ic = newiCode ('-', rv, operandFromLit (size));
2465 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2468 geniCodeAssign (op, result, 0);
2474 /*-----------------------------------------------------------------*/
2475 /* geniCodePreDec - generate code for pre decrement */
2476 /*-----------------------------------------------------------------*/
2478 geniCodePreDec (operand * op, bool lvalue)
2481 sym_link *optype = operandType (op);
2482 operand *rop = (IS_ITEMP (op) ?
2483 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2485 sym_link *roptype = operandType (rop);
2491 werror (E_LVALUE_REQUIRED, "--");
2496 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2497 if (IS_FLOAT (roptype))
2498 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2500 ic = newiCode ('-', rop, operandFromLit (size));
2501 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2504 (void) geniCodeAssign (op, result, 0);
2505 if (lvalue || IS_TRUE_SYMOP (op))
2512 /*-----------------------------------------------------------------*/
2513 /* geniCodeBitwise - gen int code for bitWise operators */
2514 /*-----------------------------------------------------------------*/
2516 geniCodeBitwise (operand * left, operand * right,
2517 int oper, sym_link * resType)
2521 left = geniCodeCast (resType, left, TRUE);
2522 right = geniCodeCast (resType, right, TRUE);
2524 ic = newiCode (oper, left, right);
2525 IC_RESULT (ic) = newiTempOperand (resType, 0);
2528 return IC_RESULT (ic);
2531 /*-----------------------------------------------------------------*/
2532 /* geniCodeAddressOf - gens icode for '&' address of operator */
2533 /*-----------------------------------------------------------------*/
2535 geniCodeAddressOf (operand * op)
2539 sym_link *optype = operandType (op);
2540 sym_link *opetype = getSpec (optype);
2542 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2544 op = operandFromOperand (op);
2549 /* lvalue check already done in decorateType */
2550 /* this must be a lvalue */
2551 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2552 /* werror (E_LVALUE_REQUIRED,"&"); */
2556 p = newLink (DECLARATOR);
2558 /* set the pointer depending on the storage class */
2559 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2561 p->next = copyLinkChain (optype);
2563 /* if already a temp */
2566 setOperandType (op, p);
2571 /* other wise make this of the type coming in */
2572 ic = newiCode (ADDRESS_OF, op, NULL);
2573 IC_RESULT (ic) = newiTempOperand (p, 1);
2574 IC_RESULT (ic)->isaddr = 0;
2576 return IC_RESULT (ic);
2578 /*-----------------------------------------------------------------*/
2579 /* setOClass - sets the output class depending on the pointer type */
2580 /*-----------------------------------------------------------------*/
2582 setOClass (sym_link * ptr, sym_link * spec)
2584 switch (DCL_TYPE (ptr))
2587 SPEC_OCLS (spec) = data;
2591 SPEC_OCLS (spec) = generic;
2595 SPEC_OCLS (spec) = xdata;
2599 SPEC_OCLS (spec) = code;
2603 SPEC_OCLS (spec) = idata;
2607 SPEC_OCLS (spec) = xstack;
2611 SPEC_OCLS (spec) = eeprom;
2620 /*-----------------------------------------------------------------*/
2621 /* geniCodeDerefPtr - dereference pointer with '*' */
2622 /*-----------------------------------------------------------------*/
2624 geniCodeDerefPtr (operand * op,int lvl)
2626 sym_link *rtype, *retype;
2627 sym_link *optype = operandType (op);
2629 // if this is an array then array access
2630 if (IS_ARRAY (optype)) {
2631 // don't worry, this will be optimized out later
2632 return geniCodeArray (op, operandFromLit (0), lvl);
2635 // just in case someone screws up
2636 wassert (IS_PTR (optype));
2638 if (IS_TRUE_SYMOP (op))
2641 op = geniCodeRValue (op, TRUE);
2644 /* now get rid of the pointer part */
2645 if (isLvaluereq(lvl) && IS_ITEMP (op))
2647 retype = getSpec (rtype = copyLinkChain (optype));
2651 retype = getSpec (rtype = copyLinkChain (optype->next));
2652 /* outputclass needs 2b updated */
2653 setOClass (optype, retype);
2656 op->isGptr = IS_GENPTR (optype);
2658 op->isaddr = (IS_PTR (rtype) ||
2659 IS_STRUCT (rtype) ||
2664 if (!isLvaluereq(lvl))
2665 op = geniCodeRValue (op, TRUE);
2667 setOperandType (op, rtype);
2672 /*-----------------------------------------------------------------*/
2673 /* geniCodeUnaryMinus - does a unary minus of the operand */
2674 /*-----------------------------------------------------------------*/
2676 geniCodeUnaryMinus (operand * op)
2679 sym_link *optype = operandType (op);
2681 if (IS_LITERAL (optype))
2682 return operandFromLit (-floatFromVal (op->operand.valOperand));
2684 ic = newiCode (UNARYMINUS, op, NULL);
2685 IC_RESULT (ic) = newiTempOperand (optype, 0);
2687 return IC_RESULT (ic);
2690 /*-----------------------------------------------------------------*/
2691 /* geniCodeLeftShift - gen i code for left shift */
2692 /*-----------------------------------------------------------------*/
2694 geniCodeLeftShift (operand * left, operand * right)
2698 ic = newiCode (LEFT_OP, left, right);
2699 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2701 return IC_RESULT (ic);
2704 /*-----------------------------------------------------------------*/
2705 /* geniCodeRightShift - gen i code for right shift */
2706 /*-----------------------------------------------------------------*/
2708 geniCodeRightShift (operand * left, operand * right)
2712 ic = newiCode (RIGHT_OP, left, right);
2713 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2715 return IC_RESULT (ic);
2718 /*-----------------------------------------------------------------*/
2719 /* geniCodeLogic- logic code */
2720 /*-----------------------------------------------------------------*/
2722 geniCodeLogic (operand * left, operand * right, int op)
2726 sym_link *rtype = operandType (right);
2727 sym_link *ltype = operandType (left);
2729 /* left is integral type and right is literal then
2730 check if the literal value is within bounds */
2731 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2733 checkConstantRange(ltype,
2734 OP_VALUE(right), "compare operation", 1);
2737 /* if one operand is a pointer and the other is a literal generic void pointer,
2738 change the type of the literal generic void pointer to match the other pointer */
2739 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2740 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2742 /* find left's definition */
2743 ic = (iCode *) setFirstItem (iCodeChain);
2746 if (((ic->op == CAST) || (ic->op == '='))
2747 && isOperandEqual(left, IC_RESULT (ic)))
2750 ic = setNextItem (iCodeChain);
2752 /* if casting literal to generic pointer, then cast to rtype instead */
2753 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2755 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2756 ltype = operandType(left);
2759 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2760 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2762 /* find right's definition */
2763 ic = (iCode *) setFirstItem (iCodeChain);
2766 if (((ic->op == CAST) || (ic->op == '='))
2767 && isOperandEqual(right, IC_RESULT (ic)))
2770 ic = setNextItem (iCodeChain);
2772 /* if casting literal to generic pointer, then cast to rtype instead */
2773 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2775 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2776 rtype = operandType(right);
2780 ctype = usualBinaryConversions (&left, &right);
2782 ic = newiCode (op, left, right);
2783 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2785 /* if comparing float
2786 and not a '==' || '!=' || '&&' || '||' (these
2788 if (IS_FLOAT(ctype) &&
2796 return IC_RESULT (ic);
2799 /*-----------------------------------------------------------------*/
2800 /* geniCodeUnary - for a a generic unary operation */
2801 /*-----------------------------------------------------------------*/
2803 geniCodeUnary (operand * op, int oper)
2805 iCode *ic = newiCode (oper, op, NULL);
2807 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2809 return IC_RESULT (ic);
2812 /*-----------------------------------------------------------------*/
2813 /* geniCodeConditional - geniCode for '?' ':' operation */
2814 /*-----------------------------------------------------------------*/
2816 geniCodeConditional (ast * tree,int lvl)
2819 symbol *falseLabel = newiTempLabel (NULL);
2820 symbol *exitLabel = newiTempLabel (NULL);
2821 operand *cond = ast2iCode (tree->left,lvl+1);
2822 operand *true, *false, *result;
2824 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2828 true = ast2iCode (tree->right->left,lvl+1);
2830 /* move the value to a new Operand */
2831 result = newiTempOperand (tree->right->ftype, 0);
2832 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2834 /* generate an unconditional goto */
2835 geniCodeGoto (exitLabel);
2837 /* now for the right side */
2838 geniCodeLabel (falseLabel);
2840 false = ast2iCode (tree->right->right,lvl+1);
2841 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2843 /* create the exit label */
2844 geniCodeLabel (exitLabel);
2849 /*-----------------------------------------------------------------*/
2850 /* geniCodeAssign - generate code for assignment */
2851 /*-----------------------------------------------------------------*/
2853 geniCodeAssign (operand * left, operand * right, int nosupdate)
2856 sym_link *ltype = operandType (left);
2857 sym_link *rtype = operandType (right);
2859 if (!left->isaddr && !IS_ITEMP (left))
2861 werror (E_LVALUE_REQUIRED, "assignment");
2865 /* left is integral type and right is literal then
2866 check if the literal value is within bounds */
2867 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2869 checkConstantRange(ltype,
2870 OP_VALUE(right), "= operation", 0);
2873 /* if the left & right type don't exactly match */
2874 /* if pointer set then make sure the check is
2875 done with the type & not the pointer */
2876 /* then cast rights type to left */
2878 /* first check the type for pointer assignement */
2879 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2880 compareType (ltype, rtype) <= 0)
2882 if (compareType (ltype->next, rtype) < 0)
2883 right = geniCodeCast (ltype->next, right, TRUE);
2885 else if (compareType (ltype, rtype) < 0)
2886 right = geniCodeCast (ltype, right, TRUE);
2888 /* If left is a true symbol & ! volatile
2889 create an assignment to temporary for
2890 the right & then assign this temporary
2891 to the symbol. This is SSA (static single
2892 assignment). Isn't it simple and folks have
2893 published mountains of paper on it */
2894 if (IS_TRUE_SYMOP (left) &&
2895 !isOperandVolatile (left, FALSE) &&
2896 isOperandGlobal (left))
2900 if (IS_TRUE_SYMOP (right))
2901 sym = OP_SYMBOL (right);
2902 ic = newiCode ('=', NULL, right);
2903 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2904 SPIL_LOC (right) = sym;
2908 ic = newiCode ('=', NULL, right);
2909 IC_RESULT (ic) = left;
2912 /* if left isgptr flag is set then support
2913 routine will be required */
2917 ic->nosupdate = nosupdate;
2921 /*-----------------------------------------------------------------*/
2922 /* geniCodeDummyRead - generate code for dummy read */
2923 /*-----------------------------------------------------------------*/
2925 geniCodeDummyRead (operand * op)
2928 sym_link *type = operandType (op);
2930 if (!IS_VOLATILE(type))
2933 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2939 /*-----------------------------------------------------------------*/
2940 /* geniCodeSEParms - generate code for side effecting fcalls */
2941 /*-----------------------------------------------------------------*/
2943 geniCodeSEParms (ast * parms,int lvl)
2948 if (parms->type == EX_OP && parms->opval.op == PARAM)
2950 geniCodeSEParms (parms->left,lvl);
2951 geniCodeSEParms (parms->right,lvl);
2955 /* hack don't like this but too lazy to think of
2957 if (IS_ADDRESS_OF_OP (parms))
2958 parms->left->lvalue = 1;
2960 if (IS_CAST_OP (parms) &&
2961 IS_PTR (parms->ftype) &&
2962 IS_ADDRESS_OF_OP (parms->right))
2963 parms->right->left->lvalue = 1;
2965 parms->opval.oprnd =
2966 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2968 parms->type = EX_OPERAND;
2969 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2970 SPEC_ARGREG(parms->ftype);
2973 /*-----------------------------------------------------------------*/
2974 /* geniCodeParms - generates parameters */
2975 /*-----------------------------------------------------------------*/
2977 geniCodeParms (ast * parms, value *argVals, int *stack,
2978 sym_link * fetype, symbol * func,int lvl)
2986 if (argVals==NULL) {
2988 argVals=FUNC_ARGS(func->type);
2991 /* if this is a param node then do the left & right */
2992 if (parms->type == EX_OP && parms->opval.op == PARAM)
2994 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2995 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2999 /* get the parameter value */
3000 if (parms->type == EX_OPERAND)
3001 pval = parms->opval.oprnd;
3004 /* maybe this else should go away ?? */
3005 /* hack don't like this but too lazy to think of
3007 if (IS_ADDRESS_OF_OP (parms))
3008 parms->left->lvalue = 1;
3010 if (IS_CAST_OP (parms) &&
3011 IS_PTR (parms->ftype) &&
3012 IS_ADDRESS_OF_OP (parms->right))
3013 parms->right->left->lvalue = 1;
3015 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3018 /* if register parm then make it a send */
3019 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3020 IFFUNC_ISBUILTIN(func->type))
3022 ic = newiCode (SEND, pval, NULL);
3023 ic->argreg = SPEC_ARGREG(parms->etype);
3024 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3029 /* now decide whether to push or assign */
3030 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3034 operand *top = operandFromSymbol (argVals->sym);
3035 /* clear useDef and other bitVectors */
3036 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3037 geniCodeAssign (top, pval, 1);
3041 sym_link *p = operandType (pval);
3043 ic = newiCode (IPUSH, pval, NULL);
3045 /* update the stack adjustment */
3046 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3051 argVals=argVals->next;
3055 /*-----------------------------------------------------------------*/
3056 /* geniCodeCall - generates temp code for calling */
3057 /*-----------------------------------------------------------------*/
3059 geniCodeCall (operand * left, ast * parms,int lvl)
3063 sym_link *type, *etype;
3066 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3067 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3068 werror (E_FUNCTION_EXPECTED);
3069 return operandFromValue(valueFromLit(0));
3072 /* take care of parameters with side-effecting
3073 function calls in them, this is required to take care
3074 of overlaying function parameters */
3075 geniCodeSEParms (parms,lvl);
3077 /* first the parameters */
3078 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3080 /* now call : if symbol then pcall */
3081 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3082 ic = newiCode (PCALL, left, NULL);
3084 ic = newiCode (CALL, left, NULL);
3087 type = copyLinkChain (operandType (left)->next);
3088 etype = getSpec (type);
3089 SPEC_EXTR (etype) = 0;
3090 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3094 /* stack adjustment after call */
3095 ic->parmBytes = stack;
3100 /*-----------------------------------------------------------------*/
3101 /* geniCodeReceive - generate intermediate code for "receive" */
3102 /*-----------------------------------------------------------------*/
3104 geniCodeReceive (value * args)
3106 /* for all arguments that are passed in registers */
3110 if (IS_REGPARM (args->etype))
3112 operand *opr = operandFromValue (args);
3114 symbol *sym = OP_SYMBOL (opr);
3117 /* we will use it after all optimizations
3118 and before liveRange calculation */
3119 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3122 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3123 options.stackAuto == 0 &&
3124 (!(options.model == MODEL_FLAT24)) )
3129 opl = newiTempOperand (args->type, 0);
3131 sym->reqv->key = sym->key;
3132 OP_SYMBOL (sym->reqv)->key = sym->key;
3133 OP_SYMBOL (sym->reqv)->isreqv = 1;
3134 OP_SYMBOL (sym->reqv)->islocal = 0;
3135 SPIL_LOC (sym->reqv) = sym;
3139 ic = newiCode (RECEIVE, NULL, NULL);
3140 ic->argreg = SPEC_ARGREG(args->etype);
3142 currFunc->recvSize = getSize (sym->type);
3145 IC_RESULT (ic) = opr;
3153 /*-----------------------------------------------------------------*/
3154 /* geniCodeFunctionBody - create the function body */
3155 /*-----------------------------------------------------------------*/
3157 geniCodeFunctionBody (ast * tree,int lvl)
3164 /* reset the auto generation */
3170 func = ast2iCode (tree->left,lvl+1);
3171 fetype = getSpec (operandType (func));
3173 savelineno = lineno;
3174 lineno = OP_SYMBOL (func)->lineDef;
3175 /* create an entry label */
3176 geniCodeLabel (entryLabel);
3177 lineno = savelineno;
3179 /* create a proc icode */
3180 ic = newiCode (FUNCTION, func, NULL);
3181 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3185 /* for all parameters that are passed
3186 on registers add a "receive" */
3187 geniCodeReceive (tree->values.args);
3189 /* generate code for the body */
3190 ast2iCode (tree->right,lvl+1);
3192 /* create a label for return */
3193 geniCodeLabel (returnLabel);
3195 /* now generate the end proc */
3196 ic = newiCode (ENDFUNCTION, func, NULL);
3201 /*-----------------------------------------------------------------*/
3202 /* geniCodeReturn - gen icode for 'return' statement */
3203 /*-----------------------------------------------------------------*/
3205 geniCodeReturn (operand * op)
3209 /* if the operand is present force an rvalue */
3211 op = geniCodeRValue (op, FALSE);
3213 ic = newiCode (RETURN, op, NULL);
3217 /*-----------------------------------------------------------------*/
3218 /* geniCodeIfx - generates code for extended if statement */
3219 /*-----------------------------------------------------------------*/
3221 geniCodeIfx (ast * tree,int lvl)
3224 operand *condition = ast2iCode (tree->left,lvl+1);
3227 /* if condition is null then exit */
3231 condition = geniCodeRValue (condition, FALSE);
3233 cetype = getSpec (operandType (condition));
3234 /* if the condition is a literal */
3235 if (IS_LITERAL (cetype))
3237 if (floatFromVal (condition->operand.valOperand))
3239 if (tree->trueLabel)
3240 geniCodeGoto (tree->trueLabel);
3246 if (tree->falseLabel)
3247 geniCodeGoto (tree->falseLabel);
3254 if (tree->trueLabel)
3256 ic = newiCodeCondition (condition,
3261 if (tree->falseLabel)
3262 geniCodeGoto (tree->falseLabel);
3266 ic = newiCodeCondition (condition,
3273 ast2iCode (tree->right,lvl+1);
3276 /*-----------------------------------------------------------------*/
3277 /* geniCodeJumpTable - tries to create a jump table for switch */
3278 /*-----------------------------------------------------------------*/
3280 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3282 int min = 0, max = 0, t, cnt = 0;
3288 int needRangeCheck = !optimize.noJTabBoundary
3289 || tree->values.switchVals.swDefault;
3291 if (!tree || !caseVals)
3294 /* the criteria for creating a jump table is */
3295 /* all integer numbers between the maximum & minimum must */
3296 /* be present , the maximum value should not exceed 255 */
3297 min = max = (int) floatFromVal (vch = caseVals);
3298 SNPRINTF (buffer, sizeof(buffer),
3300 tree->values.switchVals.swNum,
3302 addSet (&labels, newiTempLabel (buffer));
3304 /* if there is only one case value then no need */
3305 if (!(vch = vch->next))
3310 if (((t = (int) floatFromVal (vch)) - max) != 1)
3312 SNPRINTF (buffer, sizeof(buffer),
3314 tree->values.switchVals.swNum,
3316 addSet (&labels, newiTempLabel (buffer));
3322 /* if the number of case statements <= 2 then */
3323 /* it is not economical to create the jump table */
3324 /* since two compares are needed for boundary conditions */
3325 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3328 if (tree->values.switchVals.swDefault)
3330 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3334 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3338 falseLabel = newiTempLabel (buffer);
3340 /* so we can create a jumptable */
3341 /* first we rule out the boundary conditions */
3342 /* if only optimization says so */
3345 sym_link *cetype = getSpec (operandType (cond));
3346 /* no need to check the lower bound if
3347 the condition is unsigned & minimum value is zero */
3348 if (!(min == 0 && SPEC_USIGN (cetype)))
3350 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3351 ic = newiCodeCondition (boundary, falseLabel, NULL);
3355 /* now for upper bounds */
3356 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3357 ic = newiCodeCondition (boundary, falseLabel, NULL);
3361 /* if the min is not zero then we no make it zero */
3364 cond = geniCodeSubtract (cond, operandFromLit (min));
3365 if (!IS_LITERAL(getSpec(operandType(cond))))
3366 setOperandType (cond, UCHARTYPE);
3369 /* now create the jumptable */
3370 ic = newiCode (JUMPTABLE, NULL, NULL);
3371 IC_JTCOND (ic) = cond;
3372 IC_JTLABELS (ic) = labels;
3377 /*-----------------------------------------------------------------*/
3378 /* geniCodeSwitch - changes a switch to a if statement */
3379 /*-----------------------------------------------------------------*/
3381 geniCodeSwitch (ast * tree,int lvl)
3384 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3385 value *caseVals = tree->values.switchVals.swVals;
3386 symbol *trueLabel, *falseLabel;
3388 /* If the condition is a literal, then just jump to the */
3389 /* appropriate case label. */
3390 if (IS_LITERAL(getSpec(operandType(cond))))
3392 int switchVal, caseVal;
3394 switchVal = (int) floatFromVal (cond->operand.valOperand);
3397 caseVal = (int) floatFromVal (caseVals);
3398 if (caseVal == switchVal)
3400 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3401 tree->values.switchVals.swNum, caseVal);
3402 trueLabel = newiTempLabel (buffer);
3403 geniCodeGoto (trueLabel);
3406 caseVals = caseVals->next;
3408 goto defaultOrBreak;
3411 /* if we can make this a jump table */
3412 if (geniCodeJumpTable (cond, caseVals, tree))
3413 goto jumpTable; /* no need for the comparison */
3415 /* for the cases defined do */
3419 operand *compare = geniCodeLogic (cond,
3420 operandFromValue (caseVals),
3423 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3424 tree->values.switchVals.swNum,
3425 (int) floatFromVal (caseVals));
3426 trueLabel = newiTempLabel (buffer);
3428 ic = newiCodeCondition (compare, trueLabel, NULL);
3430 caseVals = caseVals->next;
3435 /* if default is present then goto break else break */
3436 if (tree->values.switchVals.swDefault)
3438 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3442 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3445 falseLabel = newiTempLabel (buffer);
3446 geniCodeGoto (falseLabel);
3449 ast2iCode (tree->right,lvl+1);
3452 /*-----------------------------------------------------------------*/
3453 /* geniCodeInline - intermediate code for inline assembler */
3454 /*-----------------------------------------------------------------*/
3456 geniCodeInline (ast * tree)
3460 ic = newiCode (INLINEASM, NULL, NULL);
3461 IC_INLINE (ic) = tree->values.inlineasm;
3465 /*-----------------------------------------------------------------*/
3466 /* geniCodeArrayInit - intermediate code for array initializer */
3467 /*-----------------------------------------------------------------*/
3469 geniCodeArrayInit (ast * tree, operand *array)
3473 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3474 ic = newiCode (ARRAYINIT, array, NULL);
3475 IC_ARRAYILIST (ic) = tree->values.constlist;
3477 operand *left=newOperand(), *right=newOperand();
3478 left->type=right->type=SYMBOL;
3479 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3480 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3481 ic = newiCode (ARRAYINIT, left, right);
3486 /*-----------------------------------------------------------------*/
3487 /* geniCodeCritical - intermediate code for a critical statement */
3488 /*-----------------------------------------------------------------*/
3490 geniCodeCritical (ast *tree, int lvl)
3495 /* If op is NULL, the original interrupt state will saved on */
3496 /* the stack. Otherwise, it will be saved in op. */
3498 /* Generate a save of the current interrupt state & disabled */
3499 ic = newiCode (CRITICAL, NULL, NULL);
3500 IC_RESULT (ic) = op;
3503 /* Generate the critical code sequence */
3504 if (tree->left && tree->left->type == EX_VALUE)
3505 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3507 ast2iCode (tree->left,lvl+1);
3509 /* Generate a restore of the original interrupt state */
3510 ic = newiCode (ENDCRITICAL, NULL, op);
3514 /*-----------------------------------------------------------------*/
3515 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3516 /* particular case. Ie : assigning or dereferencing array or ptr */
3517 /*-----------------------------------------------------------------*/
3518 set * lvaluereqSet = NULL;
3519 typedef struct lvalItem
3526 /*-----------------------------------------------------------------*/
3527 /* addLvaluereq - add a flag for lvalreq for current ast level */
3528 /*-----------------------------------------------------------------*/
3529 void addLvaluereq(int lvl)
3531 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3534 addSetHead(&lvaluereqSet,lpItem);
3537 /*-----------------------------------------------------------------*/
3538 /* delLvaluereq - del a flag for lvalreq for current ast level */
3539 /*-----------------------------------------------------------------*/
3543 lpItem = getSet(&lvaluereqSet);
3544 if(lpItem) Safe_free(lpItem);
3546 /*-----------------------------------------------------------------*/
3547 /* clearLvaluereq - clear lvalreq flag */
3548 /*-----------------------------------------------------------------*/
3549 void clearLvaluereq()
3552 lpItem = peekSet(lvaluereqSet);
3553 if(lpItem) lpItem->req = 0;
3555 /*-----------------------------------------------------------------*/
3556 /* getLvaluereq - get the last lvalreq level */
3557 /*-----------------------------------------------------------------*/
3558 int getLvaluereqLvl()
3561 lpItem = peekSet(lvaluereqSet);
3562 if(lpItem) return lpItem->lvl;
3565 /*-----------------------------------------------------------------*/
3566 /* isLvaluereq - is lvalreq valid for this level ? */
3567 /*-----------------------------------------------------------------*/
3568 int isLvaluereq(int lvl)
3571 lpItem = peekSet(lvaluereqSet);
3572 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3576 /*-----------------------------------------------------------------*/
3577 /* ast2iCode - creates an icodeList from an ast */
3578 /*-----------------------------------------------------------------*/
3580 ast2iCode (ast * tree,int lvl)
3582 operand *left = NULL;
3583 operand *right = NULL;
3587 /* set the global variables for filename & line number */
3589 filename = tree->filename;
3591 lineno = tree->lineno;
3593 block = tree->block;
3595 scopeLevel = tree->level;
3597 if (tree->type == EX_VALUE)
3598 return operandFromValue (tree->opval.val);
3600 if (tree->type == EX_LINK)
3601 return operandFromLink (tree->opval.lnk);
3603 /* if we find a nullop */
3604 if (tree->type == EX_OP &&
3605 (tree->opval.op == NULLOP ||
3606 tree->opval.op == BLOCK))
3608 if (tree->left && tree->left->type == EX_VALUE)
3609 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3611 ast2iCode (tree->left,lvl+1);
3612 if (tree->right && tree->right->type == EX_VALUE)
3613 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3615 ast2iCode (tree->right,lvl+1);
3619 /* special cases for not evaluating */
3620 if (tree->opval.op != ':' &&
3621 tree->opval.op != '?' &&
3622 tree->opval.op != CALL &&
3623 tree->opval.op != IFX &&
3624 tree->opval.op != LABEL &&
3625 tree->opval.op != GOTO &&
3626 tree->opval.op != SWITCH &&
3627 tree->opval.op != FUNCTION &&
3628 tree->opval.op != INLINEASM &&
3629 tree->opval.op != CRITICAL)
3632 if (IS_ASSIGN_OP (tree->opval.op) ||
3633 IS_DEREF_OP (tree) ||
3634 (tree->opval.op == '&' && !tree->right) ||
3635 tree->opval.op == PTR_OP)
3638 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3639 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3642 left = operandFromAst (tree->left,lvl);
3644 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3645 left = geniCodeRValue (left, TRUE);
3649 left = operandFromAst (tree->left,lvl);
3651 if (tree->opval.op == INC_OP ||
3652 tree->opval.op == DEC_OP)
3655 right = operandFromAst (tree->right,lvl);
3660 right = operandFromAst (tree->right,lvl);
3664 /* now depending on the type of operand */
3665 /* this will be a biggy */
3666 switch (tree->opval.op)
3669 case '[': /* array operation */
3671 //sym_link *ltype = operandType (left);
3672 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3673 left = geniCodeRValue (left, FALSE);
3674 right = geniCodeRValue (right, TRUE);
3677 return geniCodeArray (left, right,lvl);
3679 case '.': /* structure dereference */
3680 if (IS_PTR (operandType (left)))
3681 left = geniCodeRValue (left, TRUE);
3683 left = geniCodeRValue (left, FALSE);
3685 return geniCodeStruct (left, right, tree->lvalue);
3687 case PTR_OP: /* structure pointer dereference */
3690 pType = operandType (left);
3691 left = geniCodeRValue (left, TRUE);
3693 setOClass (pType, getSpec (operandType (left)));
3696 return geniCodeStruct (left, right, tree->lvalue);
3698 case INC_OP: /* increment operator */
3700 return geniCodePostInc (left);
3702 return geniCodePreInc (right, tree->lvalue);
3704 case DEC_OP: /* decrement operator */
3706 return geniCodePostDec (left);
3708 return geniCodePreDec (right, tree->lvalue);
3710 case '&': /* bitwise and or address of operator */
3712 { /* this is a bitwise operator */
3713 left = geniCodeRValue (left, FALSE);
3714 right = geniCodeRValue (right, FALSE);
3715 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3718 return geniCodeAddressOf (left);
3720 case '|': /* bitwise or & xor */
3722 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3723 geniCodeRValue (right, FALSE),
3728 return geniCodeDivision (geniCodeRValue (left, FALSE),
3729 geniCodeRValue (right, FALSE));
3732 return geniCodeModulus (geniCodeRValue (left, FALSE),
3733 geniCodeRValue (right, FALSE));
3736 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3737 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3739 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3743 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3744 geniCodeRValue (right, FALSE));
3746 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3750 return geniCodeAdd (geniCodeRValue (left, FALSE),
3751 geniCodeRValue (right, FALSE),lvl);
3753 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3756 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3757 geniCodeRValue (right, FALSE));
3760 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3761 geniCodeRValue (right, FALSE));
3763 #if 0 // this indeed needs a second thought
3767 // let's keep this simple: get the rvalue we need
3768 op=geniCodeRValue (right, FALSE);
3769 // now cast it to whatever we want
3770 op=geniCodeCast (operandType(left), op, FALSE);
3771 // if this is going to be used as an lvalue, make it so
3777 #else // bug #604575, is it a bug ????
3778 return geniCodeCast (operandType (left),
3779 geniCodeRValue (right, FALSE), FALSE);
3786 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3791 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3792 setOperandType (op, UCHARTYPE);
3803 /* different compilers (even different gccs) evaluate
3804 the two calls in a different order. to get the same
3805 result on all machines we've to specify a clear sequence.
3806 return geniCodeLogic (geniCodeRValue (left, FALSE),
3807 geniCodeRValue (right, FALSE),
3811 operand *leftOp, *rightOp;
3813 rightOp = geniCodeRValue (right, FALSE);
3814 leftOp = geniCodeRValue (left , FALSE);
3816 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3819 return geniCodeConditional (tree,lvl);
3822 return operandFromLit (getSize (tree->right->ftype));
3826 sym_link *rtype = operandType (right);
3827 sym_link *ltype = operandType (left);
3828 if (IS_PTR (rtype) && IS_ITEMP (right)
3829 && right->isaddr && compareType (rtype->next, ltype) == 1)
3830 right = geniCodeRValue (right, TRUE);
3832 right = geniCodeRValue (right, FALSE);
3834 geniCodeAssign (left, right, 0);
3839 geniCodeAssign (left,
3840 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3842 geniCodeRValue (right, FALSE),FALSE), 0);
3846 geniCodeAssign (left,
3847 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3849 geniCodeRValue (right, FALSE)), 0);
3852 geniCodeAssign (left,
3853 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3855 geniCodeRValue (right, FALSE)), 0);
3858 sym_link *rtype = operandType (right);
3859 sym_link *ltype = operandType (left);
3860 if (IS_PTR (rtype) && IS_ITEMP (right)
3861 && right->isaddr && compareType (rtype->next, ltype) == 1)
3862 right = geniCodeRValue (right, TRUE);
3864 right = geniCodeRValue (right, FALSE);
3867 return geniCodeAssign (left,
3868 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3874 sym_link *rtype = operandType (right);
3875 sym_link *ltype = operandType (left);
3876 if (IS_PTR (rtype) && IS_ITEMP (right)
3877 && right->isaddr && compareType (rtype->next, ltype) == 1)
3879 right = geniCodeRValue (right, TRUE);
3883 right = geniCodeRValue (right, FALSE);
3886 geniCodeAssign (left,
3887 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3893 geniCodeAssign (left,
3894 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3896 geniCodeRValue (right, FALSE)), 0);
3899 geniCodeAssign (left,
3900 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3902 geniCodeRValue (right, FALSE)), 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);
3921 geniCodeAssign (left,
3922 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3924 geniCodeRValue (right, FALSE),
3926 operandType (left)), 0);
3928 return geniCodeRValue (right, FALSE);
3931 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3934 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3935 return ast2iCode (tree->right,lvl+1);
3938 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3939 return ast2iCode (tree->right,lvl+1);
3942 geniCodeFunctionBody (tree,lvl);
3946 geniCodeReturn (right);
3950 geniCodeIfx (tree,lvl);
3954 geniCodeSwitch (tree,lvl);
3958 geniCodeInline (tree);
3962 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3966 geniCodeCritical (tree, lvl);
3972 /*-----------------------------------------------------------------*/
3973 /* reverseICChain - gets from the list and creates a linkedlist */
3974 /*-----------------------------------------------------------------*/
3981 while ((loop = getSet (&iCodeChain)))
3993 /*-----------------------------------------------------------------*/
3994 /* iCodeFromAst - given an ast will convert it to iCode */
3995 /*-----------------------------------------------------------------*/
3997 iCodeFromAst (ast * tree)
3999 returnLabel = newiTempLabel ("_return");
4000 entryLabel = newiTempLabel ("_entry");
4002 return reverseiCChain ();
4005 static const char *opTypeToStr(OPTYPE op)
4009 case SYMBOL: return "symbol";
4010 case VALUE: return "value";
4011 case TYPE: return "type";
4013 return "undefined type";
4017 operand *validateOpType(operand *op,
4024 if (op && op->type == type)
4029 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4030 " expected %s, got %s\n",
4031 macro, args, file, line,
4032 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4034 return op; // never reached, makes compiler happy.