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 /* operandLitValue - literal value of an operand */
1026 /*-----------------------------------------------------------------*/
1028 operandLitValue (operand * op)
1030 assert (isOperandLiteral (op));
1032 return floatFromVal (op->operand.valOperand);
1035 /*-----------------------------------------------------------------*/
1036 /* getBuiltInParms - returns parameters to a builtin functions */
1037 /*-----------------------------------------------------------------*/
1038 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1043 /* builtin functions uses only SEND for parameters */
1044 while (ic->op != CALL) {
1045 assert(ic->op == SEND && ic->builtinSEND);
1046 ic->generated = 1; /* mark the icode as generated */
1047 parms[*pcount] = IC_LEFT(ic);
1053 /* make sure this is a builtin function call */
1054 assert(IS_SYMOP(IC_LEFT(ic)));
1055 ftype = operandType(IC_LEFT(ic));
1056 assert(IFFUNC_ISBUILTIN(ftype));
1060 /*-----------------------------------------------------------------*/
1061 /* operandOperation - performs operations on operands */
1062 /*-----------------------------------------------------------------*/
1064 operandOperation (operand * left, operand * right,
1065 int op, sym_link * type)
1067 sym_link *let , *ret=NULL;
1068 operand *retval = (operand *) 0;
1070 assert (isOperandLiteral (left));
1071 let = getSpec(operandType(left));
1073 assert (isOperandLiteral (right));
1074 ret = getSpec(operandType(right));
1080 retval = operandFromValue (valCastLiteral (type,
1081 operandLitValue (left) +
1082 operandLitValue (right)));
1085 retval = operandFromValue (valCastLiteral (type,
1086 operandLitValue (left) -
1087 operandLitValue (right)));
1091 retval = operandFromValue (valCastLiteral (type,
1092 operandLitValue (left) *
1093 operandLitValue (right)));
1094 This could be all we've to do, but with gcc we've to take care about
1095 overflows. Two examples:
1096 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1097 significant bits are lost (52 in fraction, 63 bits would be
1098 necessary to keep full precision).
1099 If the resulting double value is greater than ULONG_MAX (resp.
1100 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1103 /* if it is not a specifier then we can assume that */
1104 /* it will be an unsigned long */
1105 if (IS_INT (type) ||
1108 /* long is handled here, because it can overflow with double */
1109 if (SPEC_LONG (type) ||
1111 /* signed and unsigned mul are the same, as long as the precision
1112 of the result isn't bigger than the precision of the operands. */
1113 retval = operandFromValue (valCastLiteral (type,
1114 (TYPE_UDWORD) operandLitValue (left) *
1115 (TYPE_UDWORD) operandLitValue (right)));
1116 else if (SPEC_USIGN (type)) /* unsigned int */
1118 /* unsigned int is handled here in order to detect overflow */
1119 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1120 (TYPE_UWORD) operandLitValue (right);
1122 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1123 if (ul != (TYPE_UWORD) ul)
1126 else /* signed int */
1128 /* signed int is handled here in order to detect overflow */
1129 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1130 (TYPE_WORD) operandLitValue (right);
1132 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1133 if (l != (TYPE_WORD) l)
1138 /* all others go here: */
1139 retval = operandFromValue (valCastLiteral (type,
1140 operandLitValue (left) *
1141 operandLitValue (right)));
1144 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1146 werror (E_DIVIDE_BY_ZERO);
1151 retval = operandFromValue (valCastLiteral (type,
1152 operandLitValue (left) /
1153 operandLitValue (right)));
1156 if ((TYPE_UDWORD) operandLitValue (right) == 0) {
1157 werror (E_DIVIDE_BY_ZERO);
1162 if (SPEC_USIGN(let) || SPEC_USIGN(ret))
1163 /* one of the operands is unsigned */
1164 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1165 (TYPE_UDWORD) operandLitValue (right));
1167 /* both operands are signed */
1168 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1169 (TYPE_DWORD) operandLitValue (right));
1173 /* The number of left shifts is always unsigned. Signed doesn't make
1174 sense here. Shifting by a negative number is impossible. */
1175 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1176 (TYPE_UDWORD) operandLitValue (right));
1179 /* The number of right shifts is always unsigned. Signed doesn't make
1180 sense here. Shifting by a negative number is impossible. */
1181 if (SPEC_USIGN(let))
1182 /* unsigned: logic shift right */
1183 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1184 (TYPE_UDWORD) operandLitValue (right));
1186 /* signed: arithmetic shift right */
1187 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1188 (TYPE_UDWORD) operandLitValue (right));
1191 /* this op doesn't care about signedness */
1195 l = (TYPE_UDWORD) operandLitValue (left);
1196 if (SPEC_NOUN(OP_VALUE(left)->type) == V_CHAR)
1198 else if (!SPEC_LONG (OP_VALUE(left)->type))
1200 r = (TYPE_UDWORD) operandLitValue (right);
1201 if (SPEC_NOUN(OP_VALUE(right)->type) == V_CHAR)
1203 else if (!SPEC_LONG (OP_VALUE(right)->type))
1205 retval = operandFromLit (l == r);
1209 retval = operandFromLit (operandLitValue (left) <
1210 operandLitValue (right));
1213 retval = operandFromLit (operandLitValue (left) <=
1214 operandLitValue (right));
1217 retval = operandFromLit (operandLitValue (left) !=
1218 operandLitValue (right));
1221 retval = operandFromLit (operandLitValue (left) >
1222 operandLitValue (right));
1225 retval = operandFromLit (operandLitValue (left) >=
1226 operandLitValue (right));
1229 retval = operandFromValue (valCastLiteral (type,
1230 (TYPE_UDWORD)operandLitValue(left) &
1231 (TYPE_UDWORD)operandLitValue(right)));
1234 retval = operandFromValue (valCastLiteral (type,
1235 (TYPE_UDWORD)operandLitValue(left) |
1236 (TYPE_UDWORD)operandLitValue(right)));
1239 retval = operandFromValue (valCastLiteral (type,
1240 (TYPE_UDWORD)operandLitValue(left) ^
1241 (TYPE_UDWORD)operandLitValue(right)));
1244 retval = operandFromLit (operandLitValue (left) &&
1245 operandLitValue (right));
1248 retval = operandFromLit (operandLitValue (left) ||
1249 operandLitValue (right));
1253 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1255 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1261 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1263 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1269 retval = operandFromValue (valCastLiteral (type,
1270 -1 * operandLitValue (left)));
1274 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1278 retval = operandFromLit (!operandLitValue (left));
1282 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1283 " operandOperation invalid operator ");
1291 /*-----------------------------------------------------------------*/
1292 /* isOperandEqual - compares two operand & return 1 if they r = */
1293 /*-----------------------------------------------------------------*/
1295 isOperandEqual (operand * left, operand * right)
1297 /* if the pointers are equal then they are equal */
1301 /* if either of them null then false */
1302 if (!left || !right)
1305 if (left->type != right->type)
1308 if (IS_SYMOP (left) && IS_SYMOP (right))
1309 return left->key == right->key;
1311 /* if types are the same */
1315 return isSymbolEqual (left->operand.symOperand,
1316 right->operand.symOperand);
1318 return (floatFromVal (left->operand.valOperand) ==
1319 floatFromVal (right->operand.valOperand));
1321 if (compareType (left->operand.typeOperand,
1322 right->operand.typeOperand) == 1)
1329 /*-------------------------------------------------------------------*/
1330 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1331 /*-------------------------------------------------------------------*/
1333 isiCodeEqual (iCode * left, iCode * right)
1335 /* if the same pointer */
1339 /* if either of them null */
1340 if (!left || !right)
1343 /* if operand are the same */
1344 if (left->op == right->op)
1347 /* compare all the elements depending on type */
1348 if (left->op != IFX)
1350 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1352 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1358 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1360 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1362 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1371 /*-----------------------------------------------------------------*/
1372 /* newiTempFromOp - create a temp Operand with same attributes */
1373 /*-----------------------------------------------------------------*/
1375 newiTempFromOp (operand * op)
1385 nop = newiTempOperand (operandType (op), TRUE);
1386 nop->isaddr = op->isaddr;
1387 nop->isvolatile = op->isvolatile;
1388 nop->isGlobal = op->isGlobal;
1389 nop->isLiteral = op->isLiteral;
1390 nop->usesDefs = op->usesDefs;
1391 nop->isParm = op->isParm;
1395 /*-----------------------------------------------------------------*/
1396 /* operand from operand - creates an operand holder for the type */
1397 /*-----------------------------------------------------------------*/
1399 operandFromOperand (operand * op)
1405 nop = newOperand ();
1406 nop->type = op->type;
1407 nop->isaddr = op->isaddr;
1409 nop->isvolatile = op->isvolatile;
1410 nop->isGlobal = op->isGlobal;
1411 nop->isLiteral = op->isLiteral;
1412 nop->usesDefs = op->usesDefs;
1413 nop->isParm = op->isParm;
1418 nop->operand.symOperand = op->operand.symOperand;
1421 nop->operand.valOperand = op->operand.valOperand;
1424 nop->operand.typeOperand = op->operand.typeOperand;
1431 /*-----------------------------------------------------------------*/
1432 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1433 /*-----------------------------------------------------------------*/
1435 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1437 operand *nop = operandFromOperand (op);
1439 if (nop->type == SYMBOL)
1441 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1442 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1448 /*-----------------------------------------------------------------*/
1449 /* operandFromSymbol - creates an operand from a symbol */
1450 /*-----------------------------------------------------------------*/
1452 operandFromSymbol (symbol * sym)
1457 /* if the symbol's type is a literal */
1458 /* then it is an enumerator type */
1459 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1460 return operandFromValue (valFromType (sym->etype));
1463 sym->key = ++operandKey;
1465 /* if this an implicit variable, means struct/union */
1466 /* member so just return it */
1467 if (sym->implicit || IS_FUNC (sym->type))
1471 op->operand.symOperand = sym;
1473 op->isvolatile = isOperandVolatile (op, TRUE);
1474 op->isGlobal = isOperandGlobal (op);
1478 /* under the following conditions create a
1479 register equivalent for a local symbol */
1480 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1481 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1482 (!(options.model == MODEL_FLAT24)) ) &&
1483 options.stackAuto == 0)
1486 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1487 !IS_FUNC (sym->type) && /* not a function */
1488 !sym->_isparm && /* not a parameter */
1489 sym->level && /* is a local variable */
1490 !sym->addrtaken && /* whose address has not been taken */
1491 !sym->reqv && /* does not already have a reg equivalence */
1492 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1493 !IS_STATIC (sym->etype) && /* and not declared static */
1494 !sym->islbl && /* not a label */
1495 ok && /* farspace check */
1496 !IS_BITVAR (sym->etype) /* not a bit variable */
1500 /* we will use it after all optimizations
1501 and before liveRange calculation */
1502 sym->reqv = newiTempOperand (sym->type, 0);
1503 sym->reqv->key = sym->key;
1504 OP_SYMBOL (sym->reqv)->key = sym->key;
1505 OP_SYMBOL (sym->reqv)->isreqv = 1;
1506 OP_SYMBOL (sym->reqv)->islocal = 1;
1507 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1508 SPIL_LOC (sym->reqv) = sym;
1511 if (!IS_AGGREGATE (sym->type))
1515 op->operand.symOperand = sym;
1518 op->isvolatile = isOperandVolatile (op, TRUE);
1519 op->isGlobal = isOperandGlobal (op);
1520 op->isPtr = IS_PTR (operandType (op));
1521 op->isParm = sym->_isparm;
1526 /* itemp = &[_symbol] */
1528 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1529 IC_LEFT (ic)->type = SYMBOL;
1530 IC_LEFT (ic)->operand.symOperand = sym;
1531 IC_LEFT (ic)->key = sym->key;
1532 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1533 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1534 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1537 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1538 if (IS_ARRAY (sym->type))
1540 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1541 IC_RESULT (ic)->isaddr = 0;
1544 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1548 return IC_RESULT (ic);
1551 /*-----------------------------------------------------------------*/
1552 /* operandFromValue - creates an operand from value */
1553 /*-----------------------------------------------------------------*/
1555 operandFromValue (value * val)
1559 /* if this is a symbol then do the symbol thing */
1561 return operandFromSymbol (val->sym);
1563 /* this is not a symbol */
1566 op->operand.valOperand = val;
1567 op->isLiteral = isOperandLiteral (op);
1571 /*-----------------------------------------------------------------*/
1572 /* operandFromLink - operand from typeChain */
1573 /*-----------------------------------------------------------------*/
1575 operandFromLink (sym_link * type)
1579 /* operand from sym_link */
1585 op->operand.typeOperand = copyLinkChain (type);
1589 /*-----------------------------------------------------------------*/
1590 /* operandFromLit - makes an operand from a literal value */
1591 /*-----------------------------------------------------------------*/
1593 operandFromLit (double i)
1595 return operandFromValue (valueFromLit (i));
1598 /*-----------------------------------------------------------------*/
1599 /* operandFromAst - creates an operand from an ast */
1600 /*-----------------------------------------------------------------*/
1602 operandFromAst (ast * tree,int lvl)
1608 /* depending on type do */
1612 return ast2iCode (tree,lvl+1);
1616 return operandFromValue (tree->opval.val);
1620 return operandFromLink (tree->opval.lnk);
1627 /* Just to keep the compiler happy */
1628 return (operand *) 0;
1631 /*-----------------------------------------------------------------*/
1632 /* setOperandType - sets the operand's type to the given type */
1633 /*-----------------------------------------------------------------*/
1635 setOperandType (operand * op, sym_link * type)
1637 /* depending on the type of operand */
1642 op->operand.valOperand->etype =
1643 getSpec (op->operand.valOperand->type =
1644 copyLinkChain (type));
1648 if (op->operand.symOperand->isitmp)
1649 op->operand.symOperand->etype =
1650 getSpec (op->operand.symOperand->type =
1651 copyLinkChain (type));
1653 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1654 "attempt to modify type of source");
1658 op->operand.typeOperand = copyLinkChain (type);
1663 /*-----------------------------------------------------------------*/
1664 /* Get size in byte of ptr need to access an array */
1665 /*-----------------------------------------------------------------*/
1667 getArraySizePtr (operand * op)
1669 sym_link *ltype = operandType(op);
1673 int size = getSize(ltype);
1674 return(IS_GENPTR(ltype)?(size-1):size);
1679 sym_link *letype = getSpec(ltype);
1680 switch (PTR_TYPE (SPEC_OCLS (letype)))
1692 return (GPTRSIZE-1);
1701 /*-----------------------------------------------------------------*/
1702 /* perform "usual unary conversions" */
1703 /*-----------------------------------------------------------------*/
1705 usualUnaryConversions (operand * op)
1707 if (IS_INTEGRAL (operandType (op)))
1709 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1712 return geniCodeCast (INTTYPE, op, TRUE);
1718 /*-----------------------------------------------------------------*/
1719 /* perform "usual binary conversions" */
1720 /*-----------------------------------------------------------------*/
1722 usualBinaryConversions (operand ** op1, operand ** op2)
1725 sym_link *rtype = operandType (*op2);
1726 sym_link *ltype = operandType (*op1);
1728 ctype = computeType (ltype, rtype);
1730 *op1 = geniCodeCast (ctype, *op1, TRUE);
1731 *op2 = geniCodeCast (ctype, *op2, TRUE);
1736 /*-----------------------------------------------------------------*/
1737 /* geniCodeValueAtAddress - generate intermeditate code for value */
1739 /*-----------------------------------------------------------------*/
1741 geniCodeRValue (operand * op, bool force)
1744 sym_link *type = operandType (op);
1745 sym_link *etype = getSpec (type);
1747 /* if this is an array & already */
1748 /* an address then return this */
1749 if (IS_AGGREGATE (type) ||
1750 (IS_PTR (type) && !force && !op->isaddr))
1751 return operandFromOperand (op);
1753 /* if this is not an address then must be */
1754 /* rvalue already so return this one */
1758 /* if this is not a temp symbol then */
1759 if (!IS_ITEMP (op) &&
1761 !IN_FARSPACE (SPEC_OCLS (etype)))
1763 op = operandFromOperand (op);
1768 if (IS_SPEC (type) &&
1769 IS_TRUE_SYMOP (op) &&
1770 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1771 (options.model == MODEL_FLAT24) ))
1773 op = operandFromOperand (op);
1778 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1779 if (IS_PTR (type) && op->isaddr && force)
1782 type = copyLinkChain (type);
1784 IC_RESULT (ic) = newiTempOperand (type, 1);
1785 IC_RESULT (ic)->isaddr = 0;
1787 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1791 return IC_RESULT (ic);
1794 /*-----------------------------------------------------------------*/
1795 /* geniCodeCast - changes the value from one type to another */
1796 /*-----------------------------------------------------------------*/
1798 geniCodeCast (sym_link * type, operand * op, bool implicit)
1802 sym_link *opetype = getSpec (optype = operandType (op));
1806 /* one of them has size zero then error */
1807 if (IS_VOID (optype))
1809 werror (E_CAST_ZERO);
1813 /* if the operand is already the desired type then do nothing */
1814 if (compareType (type, optype) == 1)
1817 /* if this is a literal then just change the type & return */
1818 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1819 return operandFromValue (valCastLiteral (type,
1820 operandLitValue (op)));
1822 /* if casting to/from pointers, do some checking */
1823 if (IS_PTR(type)) { // to a pointer
1824 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1825 if (IS_INTEGRAL(optype)) {
1826 // maybe this is NULL, than it's ok.
1827 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1828 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1829 // no way to set the storage
1830 if (IS_LITERAL(optype)) {
1831 werror(E_LITERAL_GENERIC);
1834 werror(E_NONPTR2_GENPTR);
1837 } else if (implicit) {
1838 werror(W_INTEGRAL2PTR_NOCAST);
1843 // shouldn't do that with float, array or structure unless to void
1844 if (!IS_VOID(getSpec(type)) &&
1845 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1846 werror(E_INCOMPAT_TYPES);
1850 } else { // from a pointer to a pointer
1851 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1852 // if not a pointer to a function
1853 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1854 if (implicit) { // if not to generic, they have to match
1855 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1856 werror(E_INCOMPAT_PTYPES);
1863 } else { // to a non pointer
1864 if (IS_PTR(optype)) { // from a pointer
1865 if (implicit) { // sneaky
1866 if (IS_INTEGRAL(type)) {
1867 werror(W_PTR2INTEGRAL_NOCAST);
1869 } else { // shouldn't do that with float, array or structure
1870 werror(E_INCOMPAT_TYPES);
1877 printFromToType (optype, type);
1880 /* if they are the same size create an assignment */
1881 if (getSize (type) == getSize (optype) &&
1882 !IS_BITFIELD (type) &&
1884 !IS_FLOAT (optype) &&
1885 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1886 (!IS_SPEC (type) && !IS_SPEC (optype))))
1889 ic = newiCode ('=', NULL, op);
1890 IC_RESULT (ic) = newiTempOperand (type, 0);
1891 SPIL_LOC (IC_RESULT (ic)) =
1892 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1893 IC_RESULT (ic)->isaddr = 0;
1897 ic = newiCode (CAST, operandFromLink (type),
1898 geniCodeRValue (op, FALSE));
1900 IC_RESULT (ic) = newiTempOperand (type, 0);
1903 /* preserve the storage class & output class */
1904 /* of the original variable */
1905 restype = getSpec (operandType (IC_RESULT (ic)));
1906 if (!IS_LITERAL(opetype))
1907 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1908 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1911 return IC_RESULT (ic);
1914 /*-----------------------------------------------------------------*/
1915 /* geniCodeLabel - will create a Label */
1916 /*-----------------------------------------------------------------*/
1918 geniCodeLabel (symbol * label)
1922 ic = newiCodeLabelGoto (LABEL, label);
1926 /*-----------------------------------------------------------------*/
1927 /* geniCodeGoto - will create a Goto */
1928 /*-----------------------------------------------------------------*/
1930 geniCodeGoto (symbol * label)
1934 ic = newiCodeLabelGoto (GOTO, label);
1938 /*-----------------------------------------------------------------*/
1939 /* geniCodeMultiply - gen intermediate code for multiplication */
1940 /*-----------------------------------------------------------------*/
1942 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1949 /* if they are both literal then we know the result */
1950 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1951 return operandFromValue (valMult (left->operand.valOperand,
1952 right->operand.valOperand));
1954 if (IS_LITERAL(retype)) {
1955 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1958 resType = usualBinaryConversions (&left, &right);
1960 rtype = operandType (right);
1961 retype = getSpec (rtype);
1962 ltype = operandType (left);
1963 letype = getSpec (ltype);
1967 SPEC_NOUN(getSpec(resType))=V_INT;
1970 /* if the right is a literal & power of 2 */
1971 /* then make it a left shift */
1972 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1973 efficient in most cases than 2 bytes result = 2 bytes << literal
1974 if port has 1 byte muldiv */
1975 if (p2 && !IS_FLOAT (letype) &&
1976 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1977 (port->support.muldiv == 1)))
1979 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1981 /* LEFT_OP need same size for left and result, */
1982 left = geniCodeCast (resType, left, TRUE);
1983 ltype = operandType (left);
1985 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1989 ic = newiCode ('*', left, right); /* normal multiplication */
1990 /* if the size left or right > 1 then support routine */
1991 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1995 IC_RESULT (ic) = newiTempOperand (resType, 1);
1998 return IC_RESULT (ic);
2001 /*-----------------------------------------------------------------*/
2002 /* geniCodeDivision - gen intermediate code for division */
2003 /*-----------------------------------------------------------------*/
2005 geniCodeDivision (operand * left, operand * right)
2010 sym_link *rtype = operandType (right);
2011 sym_link *retype = getSpec (rtype);
2012 sym_link *ltype = operandType (left);
2013 sym_link *letype = getSpec (ltype);
2015 resType = usualBinaryConversions (&left, &right);
2017 /* if the right is a literal & power of 2
2018 and left is unsigned then make it a
2020 if (IS_LITERAL (retype) &&
2021 !IS_FLOAT (letype) &&
2022 SPEC_USIGN(letype) &&
2023 (p2 = powof2 ((unsigned long)
2024 floatFromVal (right->operand.valOperand)))) {
2025 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2029 ic = newiCode ('/', left, right); /* normal division */
2030 /* if the size left or right > 1 then support routine */
2031 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2034 IC_RESULT (ic) = newiTempOperand (resType, 0);
2037 return IC_RESULT (ic);
2039 /*-----------------------------------------------------------------*/
2040 /* geniCodeModulus - gen intermediate code for modulus */
2041 /*-----------------------------------------------------------------*/
2043 geniCodeModulus (operand * left, operand * right)
2049 /* if they are both literal then we know the result */
2050 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2051 return operandFromValue (valMod (left->operand.valOperand,
2052 right->operand.valOperand));
2054 resType = usualBinaryConversions (&left, &right);
2056 /* now they are the same size */
2057 ic = newiCode ('%', left, right);
2059 /* if the size left or right > 1 then support routine */
2060 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2062 IC_RESULT (ic) = newiTempOperand (resType, 0);
2065 return IC_RESULT (ic);
2068 /*-----------------------------------------------------------------*/
2069 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2070 /*-----------------------------------------------------------------*/
2072 geniCodePtrPtrSubtract (operand * left, operand * right)
2078 /* if they are both literals then */
2079 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2081 result = operandFromValue (valMinus (left->operand.valOperand,
2082 right->operand.valOperand));
2086 ic = newiCode ('-', left, right);
2088 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2092 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2096 // should we really do this? is this ANSI?
2097 return geniCodeDivision (result,
2098 operandFromLit (getSize (ltype->next)));
2101 /*-----------------------------------------------------------------*/
2102 /* geniCodeSubtract - generates code for subtraction */
2103 /*-----------------------------------------------------------------*/
2105 geniCodeSubtract (operand * left, operand * right)
2112 /* if they both pointers then */
2113 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2114 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2115 return geniCodePtrPtrSubtract (left, right);
2117 /* if they are both literal then we know the result */
2118 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2119 && left->isLiteral && right->isLiteral)
2120 return operandFromValue (valMinus (left->operand.valOperand,
2121 right->operand.valOperand));
2123 /* if left is an array or pointer */
2124 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2126 isarray = left->isaddr;
2127 right = geniCodeMultiply (right,
2128 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2129 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2132 { /* make them the same size */
2133 resType = usualBinaryConversions (&left, &right);
2136 ic = newiCode ('-', left, right);
2138 IC_RESULT (ic) = newiTempOperand (resType, 1);
2139 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2141 /* if left or right is a float */
2142 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2146 return IC_RESULT (ic);
2149 /*-----------------------------------------------------------------*/
2150 /* geniCodeAdd - generates iCode for addition */
2151 /*-----------------------------------------------------------------*/
2153 geniCodeAdd (operand * left, operand * right, int lvl)
2161 /* if the right side is LITERAL zero */
2162 /* return the left side */
2163 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2166 /* if left is literal zero return right */
2167 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2170 /* if left is a pointer then size */
2171 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2173 isarray = left->isaddr;
2174 // there is no need to multiply with 1
2175 if (getSize(ltype->next)!=1) {
2176 size = operandFromLit (getSize (ltype->next));
2177 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2179 resType = copyLinkChain (ltype);
2182 { // make them the same size
2183 resType = usualBinaryConversions (&left, &right);
2186 /* if they are both literals then we know */
2187 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2188 && left->isLiteral && right->isLiteral)
2189 return operandFromValue (valPlus (valFromType (letype),
2190 valFromType (retype)));
2192 ic = newiCode ('+', left, right);
2194 IC_RESULT (ic) = newiTempOperand (resType, 1);
2195 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2197 /* if left or right is a float then support
2199 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2204 return IC_RESULT (ic);
2208 /*-----------------------------------------------------------------*/
2209 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2210 /*-----------------------------------------------------------------*/
2212 aggrToPtr (sym_link * type, bool force)
2217 if (IS_PTR (type) && !force)
2220 etype = getSpec (type);
2221 ptype = newLink (DECLARATOR);
2225 /* set the pointer depending on the storage class */
2226 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2230 /*-----------------------------------------------------------------*/
2231 /* geniCodeArray2Ptr - array to pointer */
2232 /*-----------------------------------------------------------------*/
2234 geniCodeArray2Ptr (operand * op)
2236 sym_link *optype = operandType (op);
2237 sym_link *opetype = getSpec (optype);
2239 /* set the pointer depending on the storage class */
2240 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2247 /*-----------------------------------------------------------------*/
2248 /* geniCodeArray - array access */
2249 /*-----------------------------------------------------------------*/
2251 geniCodeArray (operand * left, operand * right,int lvl)
2254 sym_link *ltype = operandType (left);
2258 if (IS_PTR (ltype->next) && left->isaddr)
2260 left = geniCodeRValue (left, FALSE);
2262 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2265 right = geniCodeMultiply (right,
2266 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2268 /* we can check for limits here */
2269 if (isOperandLiteral (right) &&
2272 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2274 werror (E_ARRAY_BOUND);
2275 right = operandFromLit (0);
2278 ic = newiCode ('+', left, right);
2280 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2281 !IS_AGGREGATE (ltype->next) &&
2282 !IS_PTR (ltype->next))
2283 ? ltype : ltype->next), 0);
2285 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2288 return IC_RESULT (ic);
2291 /*-----------------------------------------------------------------*/
2292 /* geniCodeStruct - generates intermediate code for structres */
2293 /*-----------------------------------------------------------------*/
2295 geniCodeStruct (operand * left, operand * right, bool islval)
2298 sym_link *type = operandType (left);
2299 sym_link *etype = getSpec (type);
2301 symbol *element = getStructElement (SPEC_STRUCT (etype),
2302 right->operand.symOperand);
2304 wassert(IS_SYMOP(right));
2306 /* add the offset */
2307 ic = newiCode ('+', left, operandFromLit (element->offset));
2309 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2311 /* preserve the storage & output class of the struct */
2312 /* as well as the volatile attribute */
2313 retype = getSpec (operandType (IC_RESULT (ic)));
2314 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2315 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2316 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2317 SPEC_CONST (retype) |= SPEC_CONST (etype);
2319 if (IS_PTR (element->type))
2320 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2322 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2325 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2328 /*-----------------------------------------------------------------*/
2329 /* geniCodePostInc - generate int code for Post increment */
2330 /*-----------------------------------------------------------------*/
2332 geniCodePostInc (operand * op)
2336 sym_link *optype = operandType (op);
2338 operand *rv = (IS_ITEMP (op) ?
2339 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2341 sym_link *rvtype = operandType (rv);
2344 /* if this is not an address we have trouble */
2347 werror (E_LVALUE_REQUIRED, "++");
2351 rOp = newiTempOperand (rvtype, 0);
2352 OP_SYMBOL(rOp)->noSpilLoc = 1;
2355 OP_SYMBOL(rv)->noSpilLoc = 1;
2357 geniCodeAssign (rOp, rv, 0);
2359 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2360 if (IS_FLOAT (rvtype))
2361 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2363 ic = newiCode ('+', rv, operandFromLit (size));
2365 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2368 geniCodeAssign (op, result, 0);
2374 /*-----------------------------------------------------------------*/
2375 /* geniCodePreInc - generate code for preIncrement */
2376 /*-----------------------------------------------------------------*/
2378 geniCodePreInc (operand * op, bool lvalue)
2381 sym_link *optype = operandType (op);
2382 operand *rop = (IS_ITEMP (op) ?
2383 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2385 sym_link *roptype = operandType (rop);
2391 werror (E_LVALUE_REQUIRED, "++");
2396 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2397 if (IS_FLOAT (roptype))
2398 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2400 ic = newiCode ('+', rop, operandFromLit (size));
2401 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2404 (void) geniCodeAssign (op, result, 0);
2405 if (lvalue || IS_TRUE_SYMOP (op))
2411 /*-----------------------------------------------------------------*/
2412 /* geniCodePostDec - generates code for Post decrement */
2413 /*-----------------------------------------------------------------*/
2415 geniCodePostDec (operand * op)
2419 sym_link *optype = operandType (op);
2421 operand *rv = (IS_ITEMP (op) ?
2422 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2424 sym_link *rvtype = operandType (rv);
2427 /* if this is not an address we have trouble */
2430 werror (E_LVALUE_REQUIRED, "--");
2434 rOp = newiTempOperand (rvtype, 0);
2435 OP_SYMBOL(rOp)->noSpilLoc = 1;
2438 OP_SYMBOL(rv)->noSpilLoc = 1;
2440 geniCodeAssign (rOp, rv, 0);
2442 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2443 if (IS_FLOAT (rvtype))
2444 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2446 ic = newiCode ('-', rv, operandFromLit (size));
2448 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2451 geniCodeAssign (op, result, 0);
2457 /*-----------------------------------------------------------------*/
2458 /* geniCodePreDec - generate code for pre decrement */
2459 /*-----------------------------------------------------------------*/
2461 geniCodePreDec (operand * op, bool lvalue)
2464 sym_link *optype = operandType (op);
2465 operand *rop = (IS_ITEMP (op) ?
2466 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2468 sym_link *roptype = operandType (rop);
2474 werror (E_LVALUE_REQUIRED, "--");
2479 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2480 if (IS_FLOAT (roptype))
2481 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2483 ic = newiCode ('-', rop, operandFromLit (size));
2484 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2487 (void) geniCodeAssign (op, result, 0);
2488 if (lvalue || IS_TRUE_SYMOP (op))
2495 /*-----------------------------------------------------------------*/
2496 /* geniCodeBitwise - gen int code for bitWise operators */
2497 /*-----------------------------------------------------------------*/
2499 geniCodeBitwise (operand * left, operand * right,
2500 int oper, sym_link * resType)
2504 left = geniCodeCast (resType, left, TRUE);
2505 right = geniCodeCast (resType, right, TRUE);
2507 ic = newiCode (oper, left, right);
2508 IC_RESULT (ic) = newiTempOperand (resType, 0);
2511 return IC_RESULT (ic);
2514 /*-----------------------------------------------------------------*/
2515 /* geniCodeAddressOf - gens icode for '&' address of operator */
2516 /*-----------------------------------------------------------------*/
2518 geniCodeAddressOf (operand * op)
2522 sym_link *optype = operandType (op);
2523 sym_link *opetype = getSpec (optype);
2525 /* lvalue check already done in decorateType */
2526 /* this must be a lvalue */
2527 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2528 /* werror (E_LVALUE_REQUIRED,"&"); */
2532 p = newLink (DECLARATOR);
2534 /* set the pointer depending on the storage class */
2535 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2537 p->next = copyLinkChain (optype);
2539 /* if already a temp */
2542 setOperandType (op, p);
2547 /* other wise make this of the type coming in */
2548 ic = newiCode (ADDRESS_OF, op, NULL);
2549 IC_RESULT (ic) = newiTempOperand (p, 1);
2550 IC_RESULT (ic)->isaddr = 0;
2552 return IC_RESULT (ic);
2554 /*-----------------------------------------------------------------*/
2555 /* setOClass - sets the output class depending on the pointer type */
2556 /*-----------------------------------------------------------------*/
2558 setOClass (sym_link * ptr, sym_link * spec)
2560 switch (DCL_TYPE (ptr))
2563 SPEC_OCLS (spec) = data;
2567 SPEC_OCLS (spec) = generic;
2571 SPEC_OCLS (spec) = xdata;
2575 SPEC_OCLS (spec) = code;
2579 SPEC_OCLS (spec) = idata;
2583 SPEC_OCLS (spec) = xstack;
2587 SPEC_OCLS (spec) = eeprom;
2596 /*-----------------------------------------------------------------*/
2597 /* geniCodeDerefPtr - dereference pointer with '*' */
2598 /*-----------------------------------------------------------------*/
2600 geniCodeDerefPtr (operand * op,int lvl)
2602 sym_link *rtype, *retype;
2603 sym_link *optype = operandType (op);
2605 // if this is an array then array access
2606 if (IS_ARRAY (optype)) {
2607 // don't worry, this will be optimized out later
2608 return geniCodeArray (op, operandFromLit (0), lvl);
2611 // just in case someone screws up
2612 wassert (IS_PTR (optype));
2614 if (IS_TRUE_SYMOP (op))
2617 op = geniCodeRValue (op, TRUE);
2620 /* now get rid of the pointer part */
2621 if (isLvaluereq(lvl) && IS_ITEMP (op))
2623 retype = getSpec (rtype = copyLinkChain (optype));
2627 retype = getSpec (rtype = copyLinkChain (optype->next));
2628 /* outputclass needs 2b updated */
2629 setOClass (optype, retype);
2632 op->isGptr = IS_GENPTR (optype);
2634 op->isaddr = (IS_PTR (rtype) ||
2635 IS_STRUCT (rtype) ||
2640 if (!isLvaluereq(lvl))
2641 op = geniCodeRValue (op, TRUE);
2643 setOperandType (op, rtype);
2648 /*-----------------------------------------------------------------*/
2649 /* geniCodeUnaryMinus - does a unary minus of the operand */
2650 /*-----------------------------------------------------------------*/
2652 geniCodeUnaryMinus (operand * op)
2655 sym_link *optype = operandType (op);
2657 if (IS_LITERAL (optype))
2658 return operandFromLit (-floatFromVal (op->operand.valOperand));
2660 ic = newiCode (UNARYMINUS, op, NULL);
2661 IC_RESULT (ic) = newiTempOperand (optype, 0);
2663 return IC_RESULT (ic);
2666 /*-----------------------------------------------------------------*/
2667 /* geniCodeLeftShift - gen i code for left shift */
2668 /*-----------------------------------------------------------------*/
2670 geniCodeLeftShift (operand * left, operand * right)
2674 ic = newiCode (LEFT_OP, left, right);
2675 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2677 return IC_RESULT (ic);
2680 /*-----------------------------------------------------------------*/
2681 /* geniCodeRightShift - gen i code for right shift */
2682 /*-----------------------------------------------------------------*/
2684 geniCodeRightShift (operand * left, operand * right)
2688 ic = newiCode (RIGHT_OP, left, right);
2689 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2691 return IC_RESULT (ic);
2694 /*-----------------------------------------------------------------*/
2695 /* geniCodeLogic- logic code */
2696 /*-----------------------------------------------------------------*/
2698 geniCodeLogic (operand * left, operand * right, int op)
2702 sym_link *rtype = operandType (right);
2703 sym_link *ltype = operandType (left);
2705 /* left is integral type and right is literal then
2706 check if the literal value is within bounds */
2707 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2709 checkConstantRange(ltype,
2710 OP_VALUE(right), "compare operation", 1);
2713 /* if one operand is a pointer and the other is a literal generic void pointer,
2714 change the type of the literal generic void pointer to match the other pointer */
2715 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2716 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2718 /* find left's definition */
2719 ic = (iCode *) setFirstItem (iCodeChain);
2722 if (((ic->op == CAST) || (ic->op == '='))
2723 && isOperandEqual(left, IC_RESULT (ic)))
2726 ic = setNextItem (iCodeChain);
2728 /* if casting literal to generic pointer, then cast to rtype instead */
2729 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2731 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2732 ltype = operandType(left);
2735 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2736 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2738 /* find right's definition */
2739 ic = (iCode *) setFirstItem (iCodeChain);
2742 if (((ic->op == CAST) || (ic->op == '='))
2743 && isOperandEqual(right, IC_RESULT (ic)))
2746 ic = setNextItem (iCodeChain);
2748 /* if casting literal to generic pointer, then cast to rtype instead */
2749 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2751 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2752 rtype = operandType(right);
2756 ctype = usualBinaryConversions (&left, &right);
2758 ic = newiCode (op, left, right);
2759 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2761 /* if comparing float
2762 and not a '==' || '!=' || '&&' || '||' (these
2764 if (IS_FLOAT(ctype) &&
2772 return IC_RESULT (ic);
2775 /*-----------------------------------------------------------------*/
2776 /* geniCodeUnary - for a a generic unary operation */
2777 /*-----------------------------------------------------------------*/
2779 geniCodeUnary (operand * op, int oper)
2781 iCode *ic = newiCode (oper, op, NULL);
2783 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2785 return IC_RESULT (ic);
2788 /*-----------------------------------------------------------------*/
2789 /* geniCodeConditional - geniCode for '?' ':' operation */
2790 /*-----------------------------------------------------------------*/
2792 geniCodeConditional (ast * tree,int lvl)
2795 symbol *falseLabel = newiTempLabel (NULL);
2796 symbol *exitLabel = newiTempLabel (NULL);
2797 operand *cond = ast2iCode (tree->left,lvl+1);
2798 operand *true, *false, *result;
2800 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2804 true = ast2iCode (tree->right->left,lvl+1);
2806 /* move the value to a new Operand */
2807 result = newiTempOperand (tree->right->ftype, 0);
2808 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2810 /* generate an unconditional goto */
2811 geniCodeGoto (exitLabel);
2813 /* now for the right side */
2814 geniCodeLabel (falseLabel);
2816 false = ast2iCode (tree->right->right,lvl+1);
2817 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2819 /* create the exit label */
2820 geniCodeLabel (exitLabel);
2825 /*-----------------------------------------------------------------*/
2826 /* geniCodeAssign - generate code for assignment */
2827 /*-----------------------------------------------------------------*/
2829 geniCodeAssign (operand * left, operand * right, int nosupdate)
2832 sym_link *ltype = operandType (left);
2833 sym_link *rtype = operandType (right);
2835 if (!left->isaddr && !IS_ITEMP (left))
2837 werror (E_LVALUE_REQUIRED, "assignment");
2841 /* left is integral type and right is literal then
2842 check if the literal value is within bounds */
2843 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2845 checkConstantRange(ltype,
2846 OP_VALUE(right), "= operation", 0);
2849 /* if the left & right type don't exactly match */
2850 /* if pointer set then make sure the check is
2851 done with the type & not the pointer */
2852 /* then cast rights type to left */
2854 /* first check the type for pointer assignement */
2855 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2856 compareType (ltype, rtype) <= 0)
2858 if (compareType (ltype->next, rtype) < 0)
2859 right = geniCodeCast (ltype->next, right, TRUE);
2861 else if (compareType (ltype, rtype) < 0)
2862 right = geniCodeCast (ltype, right, TRUE);
2864 /* if left is a true symbol & ! volatile
2865 create an assignment to temporary for
2866 the right & then assign this temporary
2867 to the symbol this is SSA . isn't it simple
2868 and folks have published mountains of paper on it */
2869 if (IS_TRUE_SYMOP (left) &&
2870 !isOperandVolatile (left, FALSE) &&
2871 isOperandGlobal (left))
2875 if (IS_TRUE_SYMOP (right))
2876 sym = OP_SYMBOL (right);
2877 ic = newiCode ('=', NULL, right);
2878 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2879 SPIL_LOC (right) = sym;
2883 ic = newiCode ('=', NULL, right);
2884 IC_RESULT (ic) = left;
2887 /* if left isgptr flag is set then support
2888 routine will be required */
2892 ic->nosupdate = nosupdate;
2896 /*-----------------------------------------------------------------*/
2897 /* geniCodeDummyRead - generate code for dummy read */
2898 /*-----------------------------------------------------------------*/
2900 geniCodeDummyRead (operand * op)
2903 sym_link *type = operandType (op);
2905 if (!IS_VOLATILE(type))
2908 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2914 /*-----------------------------------------------------------------*/
2915 /* geniCodeSEParms - generate code for side effecting fcalls */
2916 /*-----------------------------------------------------------------*/
2918 geniCodeSEParms (ast * parms,int lvl)
2923 if (parms->type == EX_OP && parms->opval.op == PARAM)
2925 geniCodeSEParms (parms->left,lvl);
2926 geniCodeSEParms (parms->right,lvl);
2930 /* hack don't like this but too lazy to think of
2932 if (IS_ADDRESS_OF_OP (parms))
2933 parms->left->lvalue = 1;
2935 if (IS_CAST_OP (parms) &&
2936 IS_PTR (parms->ftype) &&
2937 IS_ADDRESS_OF_OP (parms->right))
2938 parms->right->left->lvalue = 1;
2940 parms->opval.oprnd =
2941 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2943 parms->type = EX_OPERAND;
2944 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2945 SPEC_ARGREG(parms->ftype);
2948 /*-----------------------------------------------------------------*/
2949 /* geniCodeParms - generates parameters */
2950 /*-----------------------------------------------------------------*/
2952 geniCodeParms (ast * parms, value *argVals, int *stack,
2953 sym_link * fetype, symbol * func,int lvl)
2961 if (argVals==NULL) {
2963 argVals=FUNC_ARGS(func->type);
2966 /* if this is a param node then do the left & right */
2967 if (parms->type == EX_OP && parms->opval.op == PARAM)
2969 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2970 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2974 /* get the parameter value */
2975 if (parms->type == EX_OPERAND)
2976 pval = parms->opval.oprnd;
2979 /* maybe this else should go away ?? */
2980 /* hack don't like this but too lazy to think of
2982 if (IS_ADDRESS_OF_OP (parms))
2983 parms->left->lvalue = 1;
2985 if (IS_CAST_OP (parms) &&
2986 IS_PTR (parms->ftype) &&
2987 IS_ADDRESS_OF_OP (parms->right))
2988 parms->right->left->lvalue = 1;
2990 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2993 /* if register parm then make it a send */
2994 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2995 IFFUNC_ISBUILTIN(func->type))
2997 ic = newiCode (SEND, pval, NULL);
2998 ic->argreg = SPEC_ARGREG(parms->etype);
2999 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3004 /* now decide whether to push or assign */
3005 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3009 operand *top = operandFromSymbol (argVals->sym);
3010 /* clear useDef and other bitVectors */
3011 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3012 geniCodeAssign (top, pval, 1);
3016 sym_link *p = operandType (pval);
3018 ic = newiCode (IPUSH, pval, NULL);
3020 /* update the stack adjustment */
3021 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3026 argVals=argVals->next;
3030 /*-----------------------------------------------------------------*/
3031 /* geniCodeCall - generates temp code for calling */
3032 /*-----------------------------------------------------------------*/
3034 geniCodeCall (operand * left, ast * parms,int lvl)
3038 sym_link *type, *etype;
3041 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3042 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3043 werror (E_FUNCTION_EXPECTED);
3047 /* take care of parameters with side-effecting
3048 function calls in them, this is required to take care
3049 of overlaying function parameters */
3050 geniCodeSEParms (parms,lvl);
3052 /* first the parameters */
3053 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3055 /* now call : if symbol then pcall */
3056 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3057 ic = newiCode (PCALL, left, NULL);
3059 ic = newiCode (CALL, left, NULL);
3062 type = copyLinkChain (operandType (left)->next);
3063 etype = getSpec (type);
3064 SPEC_EXTR (etype) = 0;
3065 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3069 /* stack adjustment after call */
3070 ic->parmBytes = stack;
3075 /*-----------------------------------------------------------------*/
3076 /* geniCodeReceive - generate intermediate code for "receive" */
3077 /*-----------------------------------------------------------------*/
3079 geniCodeReceive (value * args)
3081 /* for all arguments that are passed in registers */
3085 if (IS_REGPARM (args->etype))
3087 operand *opr = operandFromValue (args);
3089 symbol *sym = OP_SYMBOL (opr);
3092 /* we will use it after all optimizations
3093 and before liveRange calculation */
3094 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3097 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
3098 options.stackAuto == 0 &&
3099 (!(options.model == MODEL_FLAT24)) )
3104 opl = newiTempOperand (args->type, 0);
3106 sym->reqv->key = sym->key;
3107 OP_SYMBOL (sym->reqv)->key = sym->key;
3108 OP_SYMBOL (sym->reqv)->isreqv = 1;
3109 OP_SYMBOL (sym->reqv)->islocal = 0;
3110 SPIL_LOC (sym->reqv) = sym;
3114 ic = newiCode (RECEIVE, NULL, NULL);
3115 ic->argreg = SPEC_ARGREG(args->etype);
3117 currFunc->recvSize = getSize (sym->type);
3120 IC_RESULT (ic) = opr;
3128 /*-----------------------------------------------------------------*/
3129 /* geniCodeFunctionBody - create the function body */
3130 /*-----------------------------------------------------------------*/
3132 geniCodeFunctionBody (ast * tree,int lvl)
3139 /* reset the auto generation */
3145 func = ast2iCode (tree->left,lvl+1);
3146 fetype = getSpec (operandType (func));
3148 savelineno = lineno;
3149 lineno = OP_SYMBOL (func)->lineDef;
3150 /* create an entry label */
3151 geniCodeLabel (entryLabel);
3152 lineno = savelineno;
3154 /* create a proc icode */
3155 ic = newiCode (FUNCTION, func, NULL);
3156 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3160 /* for all parameters that are passed
3161 on registers add a "receive" */
3162 geniCodeReceive (tree->values.args);
3164 /* generate code for the body */
3165 ast2iCode (tree->right,lvl+1);
3167 /* create a label for return */
3168 geniCodeLabel (returnLabel);
3170 /* now generate the end proc */
3171 ic = newiCode (ENDFUNCTION, func, NULL);
3176 /*-----------------------------------------------------------------*/
3177 /* geniCodeReturn - gen icode for 'return' statement */
3178 /*-----------------------------------------------------------------*/
3180 geniCodeReturn (operand * op)
3184 /* if the operand is present force an rvalue */
3186 op = geniCodeRValue (op, FALSE);
3188 ic = newiCode (RETURN, op, NULL);
3192 /*-----------------------------------------------------------------*/
3193 /* geniCodeIfx - generates code for extended if statement */
3194 /*-----------------------------------------------------------------*/
3196 geniCodeIfx (ast * tree,int lvl)
3199 operand *condition = ast2iCode (tree->left,lvl+1);
3202 /* if condition is null then exit */
3206 condition = geniCodeRValue (condition, FALSE);
3208 cetype = getSpec (operandType (condition));
3209 /* if the condition is a literal */
3210 if (IS_LITERAL (cetype))
3212 if (floatFromVal (condition->operand.valOperand))
3214 if (tree->trueLabel)
3215 geniCodeGoto (tree->trueLabel);
3221 if (tree->falseLabel)
3222 geniCodeGoto (tree->falseLabel);
3229 if (tree->trueLabel)
3231 ic = newiCodeCondition (condition,
3236 if (tree->falseLabel)
3237 geniCodeGoto (tree->falseLabel);
3241 ic = newiCodeCondition (condition,
3248 ast2iCode (tree->right,lvl+1);
3251 /*-----------------------------------------------------------------*/
3252 /* geniCodeJumpTable - tries to create a jump table for switch */
3253 /*-----------------------------------------------------------------*/
3255 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3257 int min = 0, max = 0, t, cnt = 0;
3263 int needRangeCheck = !optimize.noJTabBoundary
3264 || tree->values.switchVals.swDefault;
3266 if (!tree || !caseVals)
3269 /* the criteria for creating a jump table is */
3270 /* all integer numbers between the maximum & minimum must */
3271 /* be present , the maximum value should not exceed 255 */
3272 min = max = (int) floatFromVal (vch = caseVals);
3273 SNPRINTF (buffer, sizeof(buffer),
3275 tree->values.switchVals.swNum,
3277 addSet (&labels, newiTempLabel (buffer));
3279 /* if there is only one case value then no need */
3280 if (!(vch = vch->next))
3285 if (((t = (int) floatFromVal (vch)) - max) != 1)
3287 SNPRINTF (buffer, sizeof(buffer),
3289 tree->values.switchVals.swNum,
3291 addSet (&labels, newiTempLabel (buffer));
3297 /* if the number of case statements <= 2 then */
3298 /* it is not economical to create the jump table */
3299 /* since two compares are needed for boundary conditions */
3300 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3303 if (tree->values.switchVals.swDefault)
3305 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3309 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3313 falseLabel = newiTempLabel (buffer);
3315 /* so we can create a jumptable */
3316 /* first we rule out the boundary conditions */
3317 /* if only optimization says so */
3320 sym_link *cetype = getSpec (operandType (cond));
3321 /* no need to check the lower bound if
3322 the condition is unsigned & minimum value is zero */
3323 if (!(min == 0 && SPEC_USIGN (cetype)))
3325 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3326 ic = newiCodeCondition (boundary, falseLabel, NULL);
3330 /* now for upper bounds */
3331 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3332 ic = newiCodeCondition (boundary, falseLabel, NULL);
3336 /* if the min is not zero then we no make it zero */
3339 cond = geniCodeSubtract (cond, operandFromLit (min));
3340 if (!IS_LITERAL(getSpec(operandType(cond))))
3341 setOperandType (cond, UCHARTYPE);
3344 /* now create the jumptable */
3345 ic = newiCode (JUMPTABLE, NULL, NULL);
3346 IC_JTCOND (ic) = cond;
3347 IC_JTLABELS (ic) = labels;
3352 /*-----------------------------------------------------------------*/
3353 /* geniCodeSwitch - changes a switch to a if statement */
3354 /*-----------------------------------------------------------------*/
3356 geniCodeSwitch (ast * tree,int lvl)
3359 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3360 value *caseVals = tree->values.switchVals.swVals;
3361 symbol *trueLabel, *falseLabel;
3363 /* If the condition is a literal, then just jump to the */
3364 /* appropriate case label. */
3365 if (IS_LITERAL(getSpec(operandType(cond))))
3367 int switchVal, caseVal;
3369 switchVal = (int) floatFromVal (cond->operand.valOperand);
3372 caseVal = (int) floatFromVal (caseVals);
3373 if (caseVal == switchVal)
3375 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3376 tree->values.switchVals.swNum, caseVal);
3377 trueLabel = newiTempLabel (buffer);
3378 geniCodeGoto (trueLabel);
3381 caseVals = caseVals->next;
3383 goto defaultOrBreak;
3386 /* if we can make this a jump table */
3387 if (geniCodeJumpTable (cond, caseVals, tree))
3388 goto jumpTable; /* no need for the comparison */
3390 /* for the cases defined do */
3394 operand *compare = geniCodeLogic (cond,
3395 operandFromValue (caseVals),
3398 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3399 tree->values.switchVals.swNum,
3400 (int) floatFromVal (caseVals));
3401 trueLabel = newiTempLabel (buffer);
3403 ic = newiCodeCondition (compare, trueLabel, NULL);
3405 caseVals = caseVals->next;
3410 /* if default is present then goto break else break */
3411 if (tree->values.switchVals.swDefault)
3413 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3417 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3420 falseLabel = newiTempLabel (buffer);
3421 geniCodeGoto (falseLabel);
3424 ast2iCode (tree->right,lvl+1);
3427 /*-----------------------------------------------------------------*/
3428 /* geniCodeInline - intermediate code for inline assembler */
3429 /*-----------------------------------------------------------------*/
3431 geniCodeInline (ast * tree)
3435 ic = newiCode (INLINEASM, NULL, NULL);
3436 IC_INLINE (ic) = tree->values.inlineasm;
3440 /*-----------------------------------------------------------------*/
3441 /* geniCodeArrayInit - intermediate code for array initializer */
3442 /*-----------------------------------------------------------------*/
3444 geniCodeArrayInit (ast * tree, operand *array)
3448 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3449 ic = newiCode (ARRAYINIT, array, NULL);
3450 IC_ARRAYILIST (ic) = tree->values.constlist;
3452 operand *left=newOperand(), *right=newOperand();
3453 left->type=right->type=SYMBOL;
3454 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3455 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3456 ic = newiCode (ARRAYINIT, left, right);
3461 /*-----------------------------------------------------------------*/
3462 /* geniCodeCritical - intermediate code for a critical statement */
3463 /*-----------------------------------------------------------------*/
3465 geniCodeCritical (ast *tree, int lvl)
3470 /* If op is NULL, the original interrupt state will saved on */
3471 /* the stack. Otherwise, it will be saved in op. */
3473 /* Generate a save of the current interrupt state & disabled */
3474 ic = newiCode (CRITICAL, NULL, NULL);
3475 IC_RESULT (ic) = op;
3478 /* Generate the critical code sequence */
3479 if (tree->left && tree->left->type == EX_VALUE)
3480 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3482 ast2iCode (tree->left,lvl+1);
3484 /* Generate a restore of the original interrupt state */
3485 ic = newiCode (ENDCRITICAL, NULL, op);
3489 /*-----------------------------------------------------------------*/
3490 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3491 /* particular case. Ie : assigning or dereferencing array or ptr */
3492 /*-----------------------------------------------------------------*/
3493 set * lvaluereqSet = NULL;
3494 typedef struct lvalItem
3501 /*-----------------------------------------------------------------*/
3502 /* addLvaluereq - add a flag for lvalreq for current ast level */
3503 /*-----------------------------------------------------------------*/
3504 void addLvaluereq(int lvl)
3506 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3509 addSetHead(&lvaluereqSet,lpItem);
3512 /*-----------------------------------------------------------------*/
3513 /* delLvaluereq - del a flag for lvalreq for current ast level */
3514 /*-----------------------------------------------------------------*/
3518 lpItem = getSet(&lvaluereqSet);
3519 if(lpItem) Safe_free(lpItem);
3521 /*-----------------------------------------------------------------*/
3522 /* clearLvaluereq - clear lvalreq flag */
3523 /*-----------------------------------------------------------------*/
3524 void clearLvaluereq()
3527 lpItem = peekSet(lvaluereqSet);
3528 if(lpItem) lpItem->req = 0;
3530 /*-----------------------------------------------------------------*/
3531 /* getLvaluereq - get the last lvalreq level */
3532 /*-----------------------------------------------------------------*/
3533 int getLvaluereqLvl()
3536 lpItem = peekSet(lvaluereqSet);
3537 if(lpItem) return lpItem->lvl;
3540 /*-----------------------------------------------------------------*/
3541 /* isLvaluereq - is lvalreq valid for this level ? */
3542 /*-----------------------------------------------------------------*/
3543 int isLvaluereq(int lvl)
3546 lpItem = peekSet(lvaluereqSet);
3547 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3551 /*-----------------------------------------------------------------*/
3552 /* ast2iCode - creates an icodeList from an ast */
3553 /*-----------------------------------------------------------------*/
3555 ast2iCode (ast * tree,int lvl)
3557 operand *left = NULL;
3558 operand *right = NULL;
3562 /* set the global variables for filename & line number */
3564 filename = tree->filename;
3566 lineno = tree->lineno;
3568 block = tree->block;
3570 scopeLevel = tree->level;
3572 if (tree->type == EX_VALUE)
3573 return operandFromValue (tree->opval.val);
3575 if (tree->type == EX_LINK)
3576 return operandFromLink (tree->opval.lnk);
3578 /* if we find a nullop */
3579 if (tree->type == EX_OP &&
3580 (tree->opval.op == NULLOP ||
3581 tree->opval.op == BLOCK))
3583 if (tree->left && tree->left->type == EX_VALUE)
3584 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3586 ast2iCode (tree->left,lvl+1);
3587 if (tree->right && tree->right->type == EX_VALUE)
3588 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3590 ast2iCode (tree->right,lvl+1);
3594 /* special cases for not evaluating */
3595 if (tree->opval.op != ':' &&
3596 tree->opval.op != '?' &&
3597 tree->opval.op != CALL &&
3598 tree->opval.op != IFX &&
3599 tree->opval.op != LABEL &&
3600 tree->opval.op != GOTO &&
3601 tree->opval.op != SWITCH &&
3602 tree->opval.op != FUNCTION &&
3603 tree->opval.op != INLINEASM &&
3604 tree->opval.op != CRITICAL)
3607 if (IS_ASSIGN_OP (tree->opval.op) ||
3608 IS_DEREF_OP (tree) ||
3609 (tree->opval.op == '&' && !tree->right) ||
3610 tree->opval.op == PTR_OP)
3613 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3614 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3617 left = operandFromAst (tree->left,lvl);
3619 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3620 left = geniCodeRValue (left, TRUE);
3624 left = operandFromAst (tree->left,lvl);
3626 if (tree->opval.op == INC_OP ||
3627 tree->opval.op == DEC_OP)
3630 right = operandFromAst (tree->right,lvl);
3635 right = operandFromAst (tree->right,lvl);
3639 /* now depending on the type of operand */
3640 /* this will be a biggy */
3641 switch (tree->opval.op)
3644 case '[': /* array operation */
3646 //sym_link *ltype = operandType (left);
3647 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3648 left = geniCodeRValue (left, FALSE);
3649 right = geniCodeRValue (right, TRUE);
3652 return geniCodeArray (left, right,lvl);
3654 case '.': /* structure dereference */
3655 if (IS_PTR (operandType (left)))
3656 left = geniCodeRValue (left, TRUE);
3658 left = geniCodeRValue (left, FALSE);
3660 return geniCodeStruct (left, right, tree->lvalue);
3662 case PTR_OP: /* structure pointer dereference */
3665 pType = operandType (left);
3666 left = geniCodeRValue (left, TRUE);
3668 setOClass (pType, getSpec (operandType (left)));
3671 return geniCodeStruct (left, right, tree->lvalue);
3673 case INC_OP: /* increment operator */
3675 return geniCodePostInc (left);
3677 return geniCodePreInc (right, tree->lvalue);
3679 case DEC_OP: /* decrement operator */
3681 return geniCodePostDec (left);
3683 return geniCodePreDec (right, tree->lvalue);
3685 case '&': /* bitwise and or address of operator */
3687 { /* this is a bitwise operator */
3688 left = geniCodeRValue (left, FALSE);
3689 right = geniCodeRValue (right, FALSE);
3690 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3693 return geniCodeAddressOf (left);
3695 case '|': /* bitwise or & xor */
3697 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3698 geniCodeRValue (right, FALSE),
3703 return geniCodeDivision (geniCodeRValue (left, FALSE),
3704 geniCodeRValue (right, FALSE));
3707 return geniCodeModulus (geniCodeRValue (left, FALSE),
3708 geniCodeRValue (right, FALSE));
3711 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3712 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3714 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3718 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3719 geniCodeRValue (right, FALSE));
3721 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3725 return geniCodeAdd (geniCodeRValue (left, FALSE),
3726 geniCodeRValue (right, FALSE),lvl);
3728 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3731 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3732 geniCodeRValue (right, FALSE));
3735 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3736 geniCodeRValue (right, FALSE));
3738 #if 0 // this indeed needs a second thought
3742 // let's keep this simple: get the rvalue we need
3743 op=geniCodeRValue (right, FALSE);
3744 // now cast it to whatever we want
3745 op=geniCodeCast (operandType(left), op, FALSE);
3746 // if this is going to be used as an lvalue, make it so
3752 #else // bug #604575, is it a bug ????
3753 return geniCodeCast (operandType (left),
3754 geniCodeRValue (right, FALSE), FALSE);
3760 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3765 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3766 setOperandType (op, UCHARTYPE);
3777 /* different compilers (even different gccs) evaluate
3778 the two calls in a different order. to get the same
3779 result on all machines we've to specify a clear sequence.
3780 return geniCodeLogic (geniCodeRValue (left, FALSE),
3781 geniCodeRValue (right, FALSE),
3785 operand *leftOp, *rightOp;
3787 rightOp = geniCodeRValue (right, FALSE);
3788 leftOp = geniCodeRValue (left , FALSE);
3790 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3793 return geniCodeConditional (tree,lvl);
3796 return operandFromLit (getSize (tree->right->ftype));
3800 sym_link *rtype = operandType (right);
3801 sym_link *ltype = operandType (left);
3802 if (IS_PTR (rtype) && IS_ITEMP (right)
3803 && right->isaddr && compareType (rtype->next, ltype) == 1)
3804 right = geniCodeRValue (right, TRUE);
3806 right = geniCodeRValue (right, FALSE);
3808 geniCodeAssign (left, right, 0);
3813 geniCodeAssign (left,
3814 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3816 geniCodeRValue (right, FALSE),FALSE), 0);
3820 geniCodeAssign (left,
3821 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3823 geniCodeRValue (right, FALSE)), 0);
3826 geniCodeAssign (left,
3827 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3829 geniCodeRValue (right, FALSE)), 0);
3832 sym_link *rtype = operandType (right);
3833 sym_link *ltype = operandType (left);
3834 if (IS_PTR (rtype) && IS_ITEMP (right)
3835 && right->isaddr && compareType (rtype->next, ltype) == 1)
3836 right = geniCodeRValue (right, TRUE);
3838 right = geniCodeRValue (right, FALSE);
3841 return geniCodeAssign (left,
3842 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3848 sym_link *rtype = operandType (right);
3849 sym_link *ltype = operandType (left);
3850 if (IS_PTR (rtype) && IS_ITEMP (right)
3851 && right->isaddr && compareType (rtype->next, ltype) == 1)
3853 right = geniCodeRValue (right, TRUE);
3857 right = geniCodeRValue (right, FALSE);
3860 geniCodeAssign (left,
3861 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3867 geniCodeAssign (left,
3868 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3870 geniCodeRValue (right, FALSE)), 0);
3873 geniCodeAssign (left,
3874 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3876 geniCodeRValue (right, FALSE)), 0);
3879 geniCodeAssign (left,
3880 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3882 geniCodeRValue (right, FALSE),
3884 operandType (left)), 0);
3887 geniCodeAssign (left,
3888 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3890 geniCodeRValue (right, FALSE),
3892 operandType (left)), 0);
3895 geniCodeAssign (left,
3896 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3898 geniCodeRValue (right, FALSE),
3900 operandType (left)), 0);
3902 return geniCodeRValue (right, FALSE);
3905 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3908 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3909 return ast2iCode (tree->right,lvl+1);
3912 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3913 return ast2iCode (tree->right,lvl+1);
3916 geniCodeFunctionBody (tree,lvl);
3920 geniCodeReturn (right);
3924 geniCodeIfx (tree,lvl);
3928 geniCodeSwitch (tree,lvl);
3932 geniCodeInline (tree);
3936 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3940 geniCodeCritical (tree, lvl);
3946 /*-----------------------------------------------------------------*/
3947 /* reverseICChain - gets from the list and creates a linkedlist */
3948 /*-----------------------------------------------------------------*/
3955 while ((loop = getSet (&iCodeChain)))
3967 /*-----------------------------------------------------------------*/
3968 /* iCodeFromAst - given an ast will convert it to iCode */
3969 /*-----------------------------------------------------------------*/
3971 iCodeFromAst (ast * tree)
3973 returnLabel = newiTempLabel ("_return");
3974 entryLabel = newiTempLabel ("_entry");
3976 return reverseiCChain ();
3979 static const char *opTypeToStr(OPTYPE op)
3983 case SYMBOL: return "symbol";
3984 case VALUE: return "value";
3985 case TYPE: return "type";
3987 return "undefined type";
3991 operand *validateOpType(operand *op,
3998 if (op && op->type == type)
4003 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4004 " expected %s, got %s\n",
4005 macro, args, file, line,
4006 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4008 return op; // never reached, makes compiler happy.