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);
73 iCodeTable codeTable[] =
75 {'!', "not", picGenericOne, NULL},
76 {'~', "~", picGenericOne, NULL},
77 {RRC, "rrc", picGenericOne, NULL},
78 {RLC, "rlc", picGenericOne, NULL},
79 {GETHBIT, "ghbit", picGenericOne, NULL},
80 {UNARYMINUS, "-", picGenericOne, NULL},
81 {IPUSH, "push", picGenericOne, NULL},
82 {IPOP, "pop", picGenericOne, NULL},
83 {CALL, "call", picGenericOne, NULL},
84 {PCALL, "pcall", picGenericOne, NULL},
85 {FUNCTION, "proc", picGenericOne, NULL},
86 {ENDFUNCTION, "eproc", picGenericOne, NULL},
87 {RETURN, "ret", picGenericOne, NULL},
88 {'+', "+", picGeneric, NULL},
89 {'-', "-", picGeneric, NULL},
90 {'*', "*", picGeneric, NULL},
91 {'/', "/", picGeneric, NULL},
92 {'%', "%", picGeneric, NULL},
93 {'>', ">", picGeneric, NULL},
94 {'<', "<", picGeneric, NULL},
95 {LE_OP, "<=", picGeneric, NULL},
96 {GE_OP, ">=", picGeneric, NULL},
97 {EQ_OP, "==", picGeneric, NULL},
98 {NE_OP, "!=", picGeneric, NULL},
99 {AND_OP, "&&", picGeneric, NULL},
100 {OR_OP, "||", picGeneric, NULL},
101 {'^', "^", picGeneric, NULL},
102 {'|', "|", picGeneric, NULL},
103 {BITWISEAND, "&", picGeneric, NULL},
104 {LEFT_OP, "<<", picGeneric, NULL},
105 {RIGHT_OP, ">>", picGeneric, NULL},
106 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
107 {ADDRESS_OF, "&", picAddrOf, NULL},
108 {CAST, "<>", picCast, NULL},
109 {'=', ":=", picAssign, NULL},
110 {LABEL, "", picLabel, NULL},
111 {GOTO, "", picGoto, NULL},
112 {JUMPTABLE, "jtab", picJumpTable, NULL},
113 {IFX, "if", picIfx, NULL},
114 {INLINEASM, "", picInline, NULL},
115 {RECEIVE, "recv", picReceive, NULL},
116 {SEND, "send", picGenericOne, NULL},
117 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
118 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL}
121 /*-----------------------------------------------------------------*/
122 /* checkConstantRange: check a constant against the type */
123 /*-----------------------------------------------------------------*/
126 /* pedantic=0: allmost anything is allowed as long as the absolute
127 value is within the bit range of the type, and -1 is treated as
128 0xf..f for unsigned types (e.g. in assign)
129 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
130 pedantic>1: "char c=200" is not allowed (evaluates to -56)
133 void checkConstantRange(sym_link *ltype, value *val, char *msg,
140 max = pow ((double)2.0, (double)bitsForType(ltype));
142 if (SPEC_LONG(val->type)) {
143 if (SPEC_USIGN(val->type)) {
144 v=SPEC_CVAL(val->type).v_ulong;
146 v=SPEC_CVAL(val->type).v_long;
149 if (SPEC_USIGN(val->type)) {
150 v=SPEC_CVAL(val->type).v_uint;
152 v=SPEC_CVAL(val->type).v_int;
158 // this could be a good idea
159 if (options.pedantic)
163 if (SPEC_NOUN(ltype)==FLOAT) {
168 if (!SPEC_USIGN(val->type) && v<0) {
170 if (SPEC_USIGN(ltype) && (pedantic>1)) {
176 // if very pedantic: "char c=200" is not allowed
177 if (pedantic>1 && !SPEC_USIGN(ltype)) {
178 max = max/2 + negative;
185 #if 0 // temporary disabled, leaving the warning as a reminder
187 SNPRINTF (message, sizeof(message), "for %s %s in %s",
188 SPEC_USIGN(ltype) ? "unsigned" : "signed",
189 nounName(ltype), msg);
190 werror (W_CONST_RANGE, message);
198 /*-----------------------------------------------------------------*/
199 /* operandName - returns the name of the operand */
200 /*-----------------------------------------------------------------*/
202 printOperand (operand * op, FILE * file)
219 opetype = getSpec (operandType (op));
220 if (SPEC_NOUN (opetype) == V_FLOAT)
221 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
223 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
224 printTypeChain (operandType (op), file);
231 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}" , */
232 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
234 OP_LIVEFROM (op), OP_LIVETO (op),
235 OP_SYMBOL (op)->stack,
236 op->isaddr, OP_SYMBOL (op)->isreqv,
237 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
238 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
242 printTypeChain (operandType (op), file);
243 if (SPIL_LOC (op) && IS_ITEMP (op))
244 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
249 /* if assigned to registers */
250 if (OP_SYMBOL (op)->nRegs)
252 if (OP_SYMBOL (op)->isspilt)
254 if (!OP_SYMBOL (op)->remat)
255 if (OP_SYMBOL (op)->usl.spillLoc)
256 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
257 OP_SYMBOL (op)->usl.spillLoc->rname :
258 OP_SYMBOL (op)->usl.spillLoc->name));
260 fprintf (file, "[err]");
262 fprintf (file, "[remat]");
268 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
269 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
274 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
275 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
276 /* if assigned to registers */
277 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
281 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
282 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
283 OP_SYMBOL (op)->regs[i]->name :
292 printTypeChain (op->operand.typeOperand, file);
298 fprintf (file, "\n");
303 /*-----------------------------------------------------------------*/
304 /* print functions */
305 /*-----------------------------------------------------------------*/
306 PRINTFUNC (picGetValueAtAddr)
309 printOperand (IC_RESULT (ic), of);
312 printOperand (IC_LEFT (ic), of);
318 PRINTFUNC (picSetValueAtAddr)
322 printOperand (IC_LEFT (ic), of);
323 fprintf (of, "] = ");
324 printOperand (IC_RIGHT (ic), of);
328 PRINTFUNC (picAddrOf)
331 printOperand (IC_RESULT (ic), of);
332 if (IS_ITEMP (IC_LEFT (ic)))
335 fprintf (of, " = &[");
336 printOperand (IC_LEFT (ic), of);
339 if (IS_ITEMP (IC_LEFT (ic)))
340 fprintf (of, " offsetAdd ");
343 printOperand (IC_RIGHT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
351 PRINTFUNC (picJumpTable)
356 fprintf (of, "%s\t", s);
357 printOperand (IC_JTCOND (ic), of);
359 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
360 sym = setNextItem (IC_JTLABELS (ic)))
361 fprintf (of, "\t\t\t%s\n", sym->name);
364 PRINTFUNC (picGeneric)
367 printOperand (IC_RESULT (ic), of);
369 printOperand (IC_LEFT (ic), of);
370 fprintf (of, " %s ", s);
371 printOperand (IC_RIGHT (ic), of);
375 PRINTFUNC (picGenericOne)
380 printOperand (IC_RESULT (ic), of);
386 fprintf (of, "%s ", s);
387 printOperand (IC_LEFT (ic), of);
390 if (!IC_RESULT (ic) && !IC_LEFT (ic))
393 if (ic->op == SEND || ic->op == RECEIVE) {
394 fprintf(of,"{argreg = %d}",ic->argreg);
402 printOperand (IC_RESULT (ic), of);
404 printOperand (IC_LEFT (ic), of);
405 printOperand (IC_RIGHT (ic), of);
410 PRINTFUNC (picAssign)
414 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
417 printOperand (IC_RESULT (ic), of);
419 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
422 fprintf (of, " %s ", s);
423 printOperand (IC_RIGHT (ic), of);
430 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
436 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
443 printOperand (IC_COND (ic), of);
446 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
449 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
451 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
455 PRINTFUNC (picInline)
457 fprintf (of, "%s", IC_INLINE (ic));
460 PRINTFUNC (picReceive)
462 printOperand (IC_RESULT (ic), of);
463 fprintf (of, " = %s ", s);
464 printOperand (IC_LEFT (ic), of);
468 PRINTFUNC (picDummyRead)
471 fprintf (of, "%s ", s);
472 printOperand (IC_RIGHT (ic), of);
476 /*-----------------------------------------------------------------*/
477 /* piCode - prints one iCode */
478 /*-----------------------------------------------------------------*/
480 piCode (void *item, FILE * of)
488 icTab = getTableEntry (ic->op);
489 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
490 ic->filename, ic->lineno,
491 ic->seq, ic->key, ic->depth, ic->supportRtn);
492 icTab->iCodePrint (of, ic, icTab->printName);
498 printiCChain(ic,stdout);
500 /*-----------------------------------------------------------------*/
501 /* printiCChain - prints intermediate code for humans */
502 /*-----------------------------------------------------------------*/
504 printiCChain (iCode * icChain, FILE * of)
511 for (loop = icChain; loop; loop = loop->next)
513 if ((icTab = getTableEntry (loop->op)))
515 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
516 loop->filename, loop->lineno,
517 loop->seq, loop->key, loop->depth, loop->supportRtn);
519 icTab->iCodePrint (of, loop, icTab->printName);
525 /*-----------------------------------------------------------------*/
526 /* newOperand - allocate, init & return a new iCode */
527 /*-----------------------------------------------------------------*/
533 op = Safe_alloc ( sizeof (operand));
539 /*-----------------------------------------------------------------*/
540 /* newiCode - create and return a new iCode entry initialised */
541 /*-----------------------------------------------------------------*/
543 newiCode (int op, operand * left, operand * right)
547 ic = Safe_alloc ( sizeof (iCode));
550 ic->filename = filename;
552 ic->level = scopeLevel;
554 ic->key = iCodeKey++;
556 IC_RIGHT (ic) = right;
561 /*-----------------------------------------------------------------*/
562 /* newiCode for conditional statements */
563 /*-----------------------------------------------------------------*/
565 newiCodeCondition (operand * condition,
571 if (IS_VOID(operandType(condition))) {
572 werror(E_VOID_VALUE_USED);
575 ic = newiCode (IFX, NULL, NULL);
576 IC_COND (ic) = condition;
577 IC_TRUE (ic) = trueLabel;
578 IC_FALSE (ic) = falseLabel;
582 /*-----------------------------------------------------------------*/
583 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
584 /*-----------------------------------------------------------------*/
586 newiCodeLabelGoto (int op, symbol * label)
590 ic = newiCode (op, NULL, NULL);
594 IC_RIGHT (ic) = NULL;
595 IC_RESULT (ic) = NULL;
599 /*-----------------------------------------------------------------*/
600 /* newiTemp - allocate & return a newItemp Variable */
601 /*-----------------------------------------------------------------*/
609 SNPRINTF (buffer, sizeof(buffer), "%s", s);
613 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
616 itmp = newSymbol (buffer, 1);
617 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
623 /*-----------------------------------------------------------------*/
624 /* newiTempLabel - creates a temp variable label */
625 /*-----------------------------------------------------------------*/
627 newiTempLabel (char *s)
631 /* check if this alredy exists */
632 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
637 itmplbl = newSymbol (s, 1);
641 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
642 itmplbl = newSymbol (buffer, 1);
647 itmplbl->key = labelKey++;
648 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
652 /*-----------------------------------------------------------------*/
653 /* newiTempPreheaderLabel - creates a new preheader label */
654 /*-----------------------------------------------------------------*/
656 newiTempPreheaderLabel ()
660 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
661 itmplbl = newSymbol (buffer, 1);
665 itmplbl->key = labelKey++;
666 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
671 /*-----------------------------------------------------------------*/
672 /* initiCode - initialises some iCode related stuff */
673 /*-----------------------------------------------------------------*/
680 /*-----------------------------------------------------------------*/
681 /* copyiCode - make a copy of the iCode given */
682 /*-----------------------------------------------------------------*/
684 copyiCode (iCode * ic)
686 iCode *nic = newiCode (ic->op, NULL, NULL);
688 nic->lineno = ic->lineno;
689 nic->filename = ic->filename;
690 nic->block = ic->block;
691 nic->level = ic->level;
692 nic->parmBytes = ic->parmBytes;
694 /* deal with the special cases first */
698 IC_COND (nic) = operandFromOperand (IC_COND (ic));
699 IC_TRUE (nic) = IC_TRUE (ic);
700 IC_FALSE (nic) = IC_FALSE (ic);
704 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
705 IC_JTLABELS (nic) = IC_JTLABELS (ic);
710 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
711 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
715 IC_INLINE (nic) = IC_INLINE (ic);
719 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
723 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
724 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
725 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
731 /*-----------------------------------------------------------------*/
732 /* getTableEntry - gets the table entry for the given operator */
733 /*-----------------------------------------------------------------*/
735 getTableEntry (int oper)
739 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
740 if (oper == codeTable[i].icode)
741 return &codeTable[i];
746 /*-----------------------------------------------------------------*/
747 /* newiTempOperand - new intermediate temp operand */
748 /*-----------------------------------------------------------------*/
750 newiTempOperand (sym_link * type, char throwType)
753 operand *op = newOperand ();
757 itmp = newiTemp (NULL);
759 etype = getSpec (type);
761 if (IS_LITERAL (etype))
764 /* copy the type information */
766 itmp->etype = getSpec (itmp->type = (throwType ? type :
767 copyLinkChain (type)));
768 if (IS_LITERAL (itmp->etype))
770 SPEC_SCLS (itmp->etype) = S_REGISTER;
771 SPEC_OCLS (itmp->etype) = reg;
774 op->operand.symOperand = itmp;
775 op->key = itmp->key = ++operandKey;
779 /*-----------------------------------------------------------------*/
780 /* operandType - returns the type chain for an operand */
781 /*-----------------------------------------------------------------*/
783 operandType (operand * op)
785 /* depending on type of operand */
790 return op->operand.valOperand->type;
793 return op->operand.symOperand->type;
796 return op->operand.typeOperand;
798 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
799 " operand type not known ");
800 assert (0); /* should never come here */
801 /* Just to keep the compiler happy */
802 return (sym_link *) 0;
806 /*-----------------------------------------------------------------*/
807 /* isParamterToCall - will return 1 if op is a parameter to args */
808 /*-----------------------------------------------------------------*/
810 isParameterToCall (value * args, operand * op)
814 wassert (IS_SYMOP(op));
819 isSymbolEqual (op->operand.symOperand, tval->sym))
826 /*-----------------------------------------------------------------*/
827 /* isOperandGlobal - return 1 if operand is a global variable */
828 /*-----------------------------------------------------------------*/
830 isOperandGlobal (operand * op)
839 (op->operand.symOperand->level == 0 ||
840 IS_STATIC (op->operand.symOperand->etype) ||
841 IS_EXTERN (op->operand.symOperand->etype))
848 /*-----------------------------------------------------------------*/
849 /* isOperandVolatile - return 1 if the operand is volatile */
850 /*-----------------------------------------------------------------*/
852 isOperandVolatile (operand * op, bool chkTemp)
857 if (IS_ITEMP (op) && !chkTemp)
860 opetype = getSpec (optype = operandType (op));
862 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
865 if (IS_VOLATILE (opetype))
870 /*-----------------------------------------------------------------*/
871 /* isOperandLiteral - returns 1 if an operand contains a literal */
872 /*-----------------------------------------------------------------*/
874 isOperandLiteral (operand * op)
881 opetype = getSpec (operandType (op));
883 if (IS_LITERAL (opetype))
889 /*-----------------------------------------------------------------*/
890 /* isOperandInFarSpace - will return true if operand is in farSpace */
891 /*-----------------------------------------------------------------*/
893 isOperandInFarSpace (operand * op)
903 if (!IS_TRUE_SYMOP (op))
906 etype = SPIL_LOC (op)->etype;
912 etype = getSpec (operandType (op));
914 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
917 /*------------------------------------------------------------------*/
918 /* isOperandInDirSpace - will return true if operand is in dirSpace */
919 /*------------------------------------------------------------------*/
921 isOperandInDirSpace (operand * op)
931 if (!IS_TRUE_SYMOP (op))
934 etype = SPIL_LOC (op)->etype;
940 etype = getSpec (operandType (op));
942 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
945 /*--------------------------------------------------------------------*/
946 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
947 /*--------------------------------------------------------------------*/
949 isOperandInCodeSpace (operand * op)
959 etype = getSpec (operandType (op));
961 if (!IS_TRUE_SYMOP (op))
964 etype = SPIL_LOC (op)->etype;
970 etype = getSpec (operandType (op));
972 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
975 /*-----------------------------------------------------------------*/
976 /* isOperandOnStack - will return true if operand is on stack */
977 /*-----------------------------------------------------------------*/
979 isOperandOnStack (operand * op)
989 etype = getSpec (operandType (op));
990 if (IN_STACK (etype) ||
991 OP_SYMBOL(op)->onStack ||
992 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
998 /*-----------------------------------------------------------------*/
999 /* operandLitValue - literal value of an operand */
1000 /*-----------------------------------------------------------------*/
1002 operandLitValue (operand * op)
1004 assert (isOperandLiteral (op));
1006 return floatFromVal (op->operand.valOperand);
1009 /*-----------------------------------------------------------------*/
1010 /* getBuiltInParms - returns parameters to a builtin functions */
1011 /*-----------------------------------------------------------------*/
1012 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1017 /* builtin functions uses only SEND for parameters */
1018 while (ic->op != CALL) {
1019 assert(ic->op == SEND && ic->builtinSEND);
1020 ic->generated = 1; /* mark the icode as generated */
1021 parms[*pcount] = IC_LEFT(ic);
1027 /* make sure this is a builtin function call */
1028 assert(IS_SYMOP(IC_LEFT(ic)));
1029 ftype = operandType(IC_LEFT(ic));
1030 assert(IFFUNC_ISBUILTIN(ftype));
1034 /*-----------------------------------------------------------------*/
1035 /* operandOperation - performs operations on operands */
1036 /*-----------------------------------------------------------------*/
1038 operandOperation (operand * left, operand * right,
1039 int op, sym_link * type)
1041 sym_link *let , *ret=NULL;
1042 operand *retval = (operand *) 0;
1044 assert (isOperandLiteral (left));
1045 let = getSpec(operandType(left));
1047 assert (isOperandLiteral (right));
1048 ret = getSpec(operandType(right));
1054 retval = operandFromValue (valCastLiteral (type,
1055 operandLitValue (left) +
1056 operandLitValue (right)));
1059 retval = operandFromValue (valCastLiteral (type,
1060 operandLitValue (left) -
1061 operandLitValue (right)));
1065 retval = operandFromValue (valCastLiteral (type,
1066 operandLitValue (left) *
1067 operandLitValue (right)));
1068 This could be all we've to do, but with gcc we've to take care about
1069 overflows. Two examples:
1070 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1071 significant bits are lost (52 in fraction, 63 bits would be
1072 necessary to keep full precision).
1073 If the resulting double value is greater than ULONG_MAX (resp.
1074 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1077 /* if it is not a specifier then we can assume that */
1078 /* it will be an unsigned long */
1079 if (IS_INT (type) ||
1082 /* long is handled here, because it can overflow with double */
1083 if (SPEC_LONG (type) ||
1085 /* signed and unsigned mul are the same, as long as the precision
1086 of the result isn't bigger than the precision of the operands. */
1087 retval = operandFromValue (valCastLiteral (type,
1088 (TYPE_UDWORD) operandLitValue (left) *
1089 (TYPE_UDWORD) operandLitValue (right)));
1090 else if (SPEC_USIGN (type)) /* unsigned int */
1092 /* unsigned int is handled here in order to detect overflow */
1093 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1094 (TYPE_UWORD) operandLitValue (right);
1096 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1097 if (!options.lessPedantic &&
1098 ul != (TYPE_UWORD) ul)
1101 else /* signed int */
1103 /* signed int is handled here in order to detect overflow */
1104 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1105 (TYPE_WORD) operandLitValue (right);
1107 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1108 if (!options.lessPedantic &&
1114 /* all others go here: */
1115 retval = operandFromValue (valCastLiteral (type,
1116 operandLitValue (left) *
1117 operandLitValue (right)));
1120 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1122 werror (E_DIVIDE_BY_ZERO);
1127 retval = operandFromValue (valCastLiteral (type,
1128 operandLitValue (left) /
1129 operandLitValue (right)));
1132 if ((TYPE_UDWORD) operandLitValue (right) == 0) {
1133 werror (E_DIVIDE_BY_ZERO);
1138 if (SPEC_USIGN(let) || SPEC_USIGN(ret))
1139 /* one of the operands is unsigned */
1140 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1141 (TYPE_UDWORD) operandLitValue (right));
1143 /* both operands are signed */
1144 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1145 (TYPE_DWORD) operandLitValue (right));
1149 /* The number of left shifts is always unsigned. Signed doesn't make
1150 sense here. Shifting by a negative number is impossible. */
1151 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1152 (TYPE_UDWORD) operandLitValue (right));
1155 /* The number of right shifts is always unsigned. Signed doesn't make
1156 sense here. Shifting by a negative number is impossible. */
1157 if (SPEC_USIGN(let))
1158 /* unsigned: logic shift right */
1159 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1160 (TYPE_UDWORD) operandLitValue (right));
1162 /* signed: arithmetic shift right */
1163 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1164 (TYPE_UDWORD) operandLitValue (right));
1167 /* this op doesn't care about signedness */
1171 l = (TYPE_UDWORD) operandLitValue (left);
1172 if (SPEC_NOUN(OP_VALUE(left)->type) == V_CHAR)
1174 else if (!SPEC_LONG (OP_VALUE(left)->type))
1176 r = (TYPE_UDWORD) operandLitValue (right);
1177 if (SPEC_NOUN(OP_VALUE(right)->type) == V_CHAR)
1179 else if (!SPEC_LONG (OP_VALUE(right)->type))
1181 retval = operandFromLit (l == r);
1185 retval = operandFromLit (operandLitValue (left) <
1186 operandLitValue (right));
1189 retval = operandFromLit (operandLitValue (left) <=
1190 operandLitValue (right));
1193 retval = operandFromLit (operandLitValue (left) !=
1194 operandLitValue (right));
1197 retval = operandFromLit (operandLitValue (left) >
1198 operandLitValue (right));
1201 retval = operandFromLit (operandLitValue (left) >=
1202 operandLitValue (right));
1205 retval = operandFromValue (valCastLiteral (type,
1206 (TYPE_UDWORD)operandLitValue(left) &
1207 (TYPE_UDWORD)operandLitValue(right)));
1210 retval = operandFromValue (valCastLiteral (type,
1211 (TYPE_UDWORD)operandLitValue(left) |
1212 (TYPE_UDWORD)operandLitValue(right)));
1215 retval = operandFromValue (valCastLiteral (type,
1216 (TYPE_UDWORD)operandLitValue(left) ^
1217 (TYPE_UDWORD)operandLitValue(right)));
1220 retval = operandFromLit (operandLitValue (left) &&
1221 operandLitValue (right));
1224 retval = operandFromLit (operandLitValue (left) ||
1225 operandLitValue (right));
1229 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1231 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1237 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1239 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1245 retval = operandFromValue (valCastLiteral (type,
1246 -1 * operandLitValue (left)));
1250 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1254 retval = operandFromLit (!operandLitValue (left));
1258 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1259 " operandOperation invalid operator ");
1267 /*-----------------------------------------------------------------*/
1268 /* isOperandEqual - compares two operand & return 1 if they r = */
1269 /*-----------------------------------------------------------------*/
1271 isOperandEqual (operand * left, operand * right)
1273 /* if the pointers are equal then they are equal */
1277 /* if either of them null then false */
1278 if (!left || !right)
1281 if (left->type != right->type)
1284 if (IS_SYMOP (left) && IS_SYMOP (right))
1285 return left->key == right->key;
1287 /* if types are the same */
1291 return isSymbolEqual (left->operand.symOperand,
1292 right->operand.symOperand);
1294 return (floatFromVal (left->operand.valOperand) ==
1295 floatFromVal (right->operand.valOperand));
1297 if (compareType (left->operand.typeOperand,
1298 right->operand.typeOperand) == 1)
1305 /*-------------------------------------------------------------------*/
1306 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1307 /*-------------------------------------------------------------------*/
1309 isiCodeEqual (iCode * left, iCode * right)
1311 /* if the same pointer */
1315 /* if either of them null */
1316 if (!left || !right)
1319 /* if operand are the same */
1320 if (left->op == right->op)
1323 /* compare all the elements depending on type */
1324 if (left->op != IFX)
1326 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1328 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1334 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1336 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1338 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1347 /*-----------------------------------------------------------------*/
1348 /* newiTempFromOp - create a temp Operand with same attributes */
1349 /*-----------------------------------------------------------------*/
1351 newiTempFromOp (operand * op)
1361 nop = newiTempOperand (operandType (op), TRUE);
1362 nop->isaddr = op->isaddr;
1363 nop->isvolatile = op->isvolatile;
1364 nop->isGlobal = op->isGlobal;
1365 nop->isLiteral = op->isLiteral;
1366 nop->usesDefs = op->usesDefs;
1367 nop->isParm = op->isParm;
1371 /*-----------------------------------------------------------------*/
1372 /* operand from operand - creates an operand holder for the type */
1373 /*-----------------------------------------------------------------*/
1375 operandFromOperand (operand * op)
1381 nop = newOperand ();
1382 nop->type = op->type;
1383 nop->isaddr = op->isaddr;
1385 nop->isvolatile = op->isvolatile;
1386 nop->isGlobal = op->isGlobal;
1387 nop->isLiteral = op->isLiteral;
1388 nop->usesDefs = op->usesDefs;
1389 nop->isParm = op->isParm;
1394 nop->operand.symOperand = op->operand.symOperand;
1397 nop->operand.valOperand = op->operand.valOperand;
1400 nop->operand.typeOperand = op->operand.typeOperand;
1407 /*-----------------------------------------------------------------*/
1408 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1409 /*-----------------------------------------------------------------*/
1411 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1413 operand *nop = operandFromOperand (op);
1415 if (nop->type == SYMBOL)
1417 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1418 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1424 /*-----------------------------------------------------------------*/
1425 /* operandFromSymbol - creates an operand from a symbol */
1426 /*-----------------------------------------------------------------*/
1428 operandFromSymbol (symbol * sym)
1433 /* if the symbol's type is a literal */
1434 /* then it is an enumerator type */
1435 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1436 return operandFromValue (valFromType (sym->etype));
1439 sym->key = ++operandKey;
1441 /* if this an implicit variable, means struct/union */
1442 /* member so just return it */
1443 if (sym->implicit || IS_FUNC (sym->type))
1447 op->operand.symOperand = sym;
1449 op->isvolatile = isOperandVolatile (op, TRUE);
1450 op->isGlobal = isOperandGlobal (op);
1454 /* under the following conditions create a
1455 register equivalent for a local symbol */
1456 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1457 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1458 (!(options.model == MODEL_FLAT24)) ) &&
1459 options.stackAuto == 0)
1462 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1463 !IS_FUNC (sym->type) && /* not a function */
1464 !sym->_isparm && /* not a parameter */
1465 sym->level && /* is a local variable */
1466 !sym->addrtaken && /* whose address has not been taken */
1467 !sym->reqv && /* does not already have a reg equivalence */
1468 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1469 !IS_STATIC (sym->etype) && /* and not declared static */
1470 !sym->islbl && /* not a label */
1471 ok && /* farspace check */
1472 !IS_BITVAR (sym->etype) /* not a bit variable */
1476 /* we will use it after all optimizations
1477 and before liveRange calculation */
1478 sym->reqv = newiTempOperand (sym->type, 0);
1479 sym->reqv->key = sym->key;
1480 OP_SYMBOL (sym->reqv)->key = sym->key;
1481 OP_SYMBOL (sym->reqv)->isreqv = 1;
1482 OP_SYMBOL (sym->reqv)->islocal = 1;
1483 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1484 SPIL_LOC (sym->reqv) = sym;
1487 if (!IS_AGGREGATE (sym->type))
1491 op->operand.symOperand = sym;
1494 op->isvolatile = isOperandVolatile (op, TRUE);
1495 op->isGlobal = isOperandGlobal (op);
1496 op->isPtr = IS_PTR (operandType (op));
1497 op->isParm = sym->_isparm;
1502 /* itemp = &[_symbol] */
1504 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1505 IC_LEFT (ic)->type = SYMBOL;
1506 IC_LEFT (ic)->operand.symOperand = sym;
1507 IC_LEFT (ic)->key = sym->key;
1508 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1509 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1510 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1513 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1514 if (IS_ARRAY (sym->type))
1516 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1517 IC_RESULT (ic)->isaddr = 0;
1520 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1524 return IC_RESULT (ic);
1527 /*-----------------------------------------------------------------*/
1528 /* operandFromValue - creates an operand from value */
1529 /*-----------------------------------------------------------------*/
1531 operandFromValue (value * val)
1535 /* if this is a symbol then do the symbol thing */
1537 return operandFromSymbol (val->sym);
1539 /* this is not a symbol */
1542 op->operand.valOperand = val;
1543 op->isLiteral = isOperandLiteral (op);
1547 /*-----------------------------------------------------------------*/
1548 /* operandFromLink - operand from typeChain */
1549 /*-----------------------------------------------------------------*/
1551 operandFromLink (sym_link * type)
1555 /* operand from sym_link */
1561 op->operand.typeOperand = copyLinkChain (type);
1565 /*-----------------------------------------------------------------*/
1566 /* operandFromLit - makes an operand from a literal value */
1567 /*-----------------------------------------------------------------*/
1569 operandFromLit (double i)
1571 return operandFromValue (valueFromLit (i));
1574 /*-----------------------------------------------------------------*/
1575 /* operandFromAst - creates an operand from an ast */
1576 /*-----------------------------------------------------------------*/
1578 operandFromAst (ast * tree,int lvl)
1584 /* depending on type do */
1588 return ast2iCode (tree,lvl+1);
1592 return operandFromValue (tree->opval.val);
1596 return operandFromLink (tree->opval.lnk);
1603 /* Just to keep the compiler happy */
1604 return (operand *) 0;
1607 /*-----------------------------------------------------------------*/
1608 /* setOperandType - sets the operand's type to the given type */
1609 /*-----------------------------------------------------------------*/
1611 setOperandType (operand * op, sym_link * type)
1613 /* depending on the type of operand */
1618 op->operand.valOperand->etype =
1619 getSpec (op->operand.valOperand->type =
1620 copyLinkChain (type));
1624 if (op->operand.symOperand->isitmp)
1625 op->operand.symOperand->etype =
1626 getSpec (op->operand.symOperand->type =
1627 copyLinkChain (type));
1629 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1630 "attempt to modify type of source");
1634 op->operand.typeOperand = copyLinkChain (type);
1639 /*-----------------------------------------------------------------*/
1640 /* Get size in byte of ptr need to access an array */
1641 /*-----------------------------------------------------------------*/
1643 getArraySizePtr (operand * op)
1645 sym_link *ltype = operandType(op);
1649 int size = getSize(ltype);
1650 return(IS_GENPTR(ltype)?(size-1):size);
1655 sym_link *letype = getSpec(ltype);
1656 switch (PTR_TYPE (SPEC_OCLS (letype)))
1668 return (GPTRSIZE-1);
1677 /*-----------------------------------------------------------------*/
1678 /* perform "usual unary conversions" */
1679 /*-----------------------------------------------------------------*/
1681 usualUnaryConversions (operand * op)
1683 if (IS_INTEGRAL (operandType (op)))
1685 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1688 return geniCodeCast (INTTYPE, op, TRUE);
1694 /*-----------------------------------------------------------------*/
1695 /* perform "usual binary conversions" */
1696 /*-----------------------------------------------------------------*/
1698 usualBinaryConversions (operand ** op1, operand ** op2)
1701 sym_link *rtype = operandType (*op2);
1702 sym_link *ltype = operandType (*op1);
1704 ctype = computeType (ltype, rtype);
1706 *op1 = geniCodeCast (ctype, *op1, TRUE);
1707 *op2 = geniCodeCast (ctype, *op2, TRUE);
1712 /*-----------------------------------------------------------------*/
1713 /* geniCodeValueAtAddress - generate intermeditate code for value */
1715 /*-----------------------------------------------------------------*/
1717 geniCodeRValue (operand * op, bool force)
1720 sym_link *type = operandType (op);
1721 sym_link *etype = getSpec (type);
1723 /* if this is an array & already */
1724 /* an address then return this */
1725 if (IS_AGGREGATE (type) ||
1726 (IS_PTR (type) && !force && !op->isaddr))
1727 return operandFromOperand (op);
1729 /* if this is not an address then must be */
1730 /* rvalue already so return this one */
1734 /* if this is not a temp symbol then */
1735 if (!IS_ITEMP (op) &&
1737 !IN_FARSPACE (SPEC_OCLS (etype)))
1739 op = operandFromOperand (op);
1744 if (IS_SPEC (type) &&
1745 IS_TRUE_SYMOP (op) &&
1746 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1747 (options.model == MODEL_FLAT24) ))
1749 op = operandFromOperand (op);
1754 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1755 if (IS_PTR (type) && op->isaddr && force)
1758 type = copyLinkChain (type);
1760 IC_RESULT (ic) = newiTempOperand (type, 1);
1761 IC_RESULT (ic)->isaddr = 0;
1763 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1767 return IC_RESULT (ic);
1770 /*-----------------------------------------------------------------*/
1771 /* geniCodeCast - changes the value from one type to another */
1772 /*-----------------------------------------------------------------*/
1774 geniCodeCast (sym_link * type, operand * op, bool implicit)
1778 sym_link *opetype = getSpec (optype = operandType (op));
1782 /* one of them has size zero then error */
1783 if (IS_VOID (optype))
1785 werror (E_CAST_ZERO);
1789 /* if the operand is already the desired type then do nothing */
1790 if (compareType (type, optype) == 1)
1793 /* if this is a literal then just change the type & return */
1794 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1795 return operandFromValue (valCastLiteral (type,
1796 operandLitValue (op)));
1798 /* if casting to/from pointers, do some checking */
1799 if (IS_PTR(type)) { // to a pointer
1800 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1801 if (IS_INTEGRAL(optype)) {
1802 // maybe this is NULL, than it's ok.
1803 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1804 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1805 // no way to set the storage
1806 if (IS_LITERAL(optype)) {
1807 werror(E_LITERAL_GENERIC);
1810 werror(E_NONPTR2_GENPTR);
1813 } else if (implicit) {
1814 werror(W_INTEGRAL2PTR_NOCAST);
1819 // shouldn't do that with float, array or structure unless to void
1820 if (!IS_VOID(getSpec(type)) &&
1821 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1822 werror(E_INCOMPAT_TYPES);
1826 } else { // from a pointer to a pointer
1827 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1828 // if not a pointer to a function
1829 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1830 if (implicit) { // if not to generic, they have to match
1831 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1832 werror(E_INCOMPAT_PTYPES);
1839 } else { // to a non pointer
1840 if (IS_PTR(optype)) { // from a pointer
1841 if (implicit) { // sneaky
1842 if (IS_INTEGRAL(type)) {
1843 werror(W_PTR2INTEGRAL_NOCAST);
1845 } else { // shouldn't do that with float, array or structure
1846 werror(E_INCOMPAT_TYPES);
1853 printFromToType (optype, type);
1856 /* if they are the same size create an assignment */
1857 if (getSize (type) == getSize (optype) &&
1858 !IS_BITFIELD (type) &&
1860 !IS_FLOAT (optype) &&
1861 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1862 (!IS_SPEC (type) && !IS_SPEC (optype))))
1865 ic = newiCode ('=', NULL, op);
1866 IC_RESULT (ic) = newiTempOperand (type, 0);
1867 SPIL_LOC (IC_RESULT (ic)) =
1868 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1869 IC_RESULT (ic)->isaddr = 0;
1873 ic = newiCode (CAST, operandFromLink (type),
1874 geniCodeRValue (op, FALSE));
1876 IC_RESULT (ic) = newiTempOperand (type, 0);
1879 /* preserve the storage class & output class */
1880 /* of the original variable */
1881 restype = getSpec (operandType (IC_RESULT (ic)));
1882 if (!IS_LITERAL(opetype))
1883 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1884 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1887 return IC_RESULT (ic);
1890 /*-----------------------------------------------------------------*/
1891 /* geniCodeLabel - will create a Label */
1892 /*-----------------------------------------------------------------*/
1894 geniCodeLabel (symbol * label)
1898 ic = newiCodeLabelGoto (LABEL, label);
1902 /*-----------------------------------------------------------------*/
1903 /* geniCodeGoto - will create a Goto */
1904 /*-----------------------------------------------------------------*/
1906 geniCodeGoto (symbol * label)
1910 ic = newiCodeLabelGoto (GOTO, label);
1914 /*-----------------------------------------------------------------*/
1915 /* geniCodeMultiply - gen intermediate code for multiplication */
1916 /*-----------------------------------------------------------------*/
1918 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1925 /* if they are both literal then we know the result */
1926 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1927 return operandFromValue (valMult (left->operand.valOperand,
1928 right->operand.valOperand));
1930 if (IS_LITERAL(retype)) {
1931 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1934 resType = usualBinaryConversions (&left, &right);
1936 rtype = operandType (right);
1937 retype = getSpec (rtype);
1938 ltype = operandType (left);
1939 letype = getSpec (ltype);
1943 SPEC_NOUN(getSpec(resType))=V_INT;
1946 /* if the right is a literal & power of 2 */
1947 /* then make it a left shift */
1948 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1949 efficient in most cases than 2 bytes result = 2 bytes << literal
1950 if port has 1 byte muldiv */
1951 if (p2 && !IS_FLOAT (letype) &&
1952 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1953 (port->support.muldiv == 1)))
1955 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1957 /* LEFT_OP need same size for left and result, */
1958 left = geniCodeCast (resType, left, TRUE);
1959 ltype = operandType (left);
1961 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1965 ic = newiCode ('*', left, right); /* normal multiplication */
1966 /* if the size left or right > 1 then support routine */
1967 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1971 IC_RESULT (ic) = newiTempOperand (resType, 1);
1974 return IC_RESULT (ic);
1977 /*-----------------------------------------------------------------*/
1978 /* geniCodeDivision - gen intermediate code for division */
1979 /*-----------------------------------------------------------------*/
1981 geniCodeDivision (operand * left, operand * right)
1986 sym_link *rtype = operandType (right);
1987 sym_link *retype = getSpec (rtype);
1988 sym_link *ltype = operandType (left);
1989 sym_link *letype = getSpec (ltype);
1991 resType = usualBinaryConversions (&left, &right);
1993 /* if the right is a literal & power of 2
1994 and left is unsigned then make it a
1996 if (IS_LITERAL (retype) &&
1997 !IS_FLOAT (letype) &&
1998 SPEC_USIGN(letype) &&
1999 (p2 = powof2 ((unsigned long)
2000 floatFromVal (right->operand.valOperand)))) {
2001 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2005 ic = newiCode ('/', left, right); /* normal division */
2006 /* if the size left or right > 1 then support routine */
2007 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2010 IC_RESULT (ic) = newiTempOperand (resType, 0);
2013 return IC_RESULT (ic);
2015 /*-----------------------------------------------------------------*/
2016 /* geniCodeModulus - gen intermediate code for modulus */
2017 /*-----------------------------------------------------------------*/
2019 geniCodeModulus (operand * left, operand * right)
2025 /* if they are both literal then we know the result */
2026 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2027 return operandFromValue (valMod (left->operand.valOperand,
2028 right->operand.valOperand));
2030 resType = usualBinaryConversions (&left, &right);
2032 /* now they are the same size */
2033 ic = newiCode ('%', left, right);
2035 /* if the size left or right > 1 then support routine */
2036 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2038 IC_RESULT (ic) = newiTempOperand (resType, 0);
2041 return IC_RESULT (ic);
2044 /*-----------------------------------------------------------------*/
2045 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2046 /*-----------------------------------------------------------------*/
2048 geniCodePtrPtrSubtract (operand * left, operand * right)
2054 /* if they are both literals then */
2055 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2057 result = operandFromValue (valMinus (left->operand.valOperand,
2058 right->operand.valOperand));
2062 ic = newiCode ('-', left, right);
2064 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2068 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2072 // should we really do this? is this ANSI?
2073 return geniCodeDivision (result,
2074 operandFromLit (getSize (ltype->next)));
2077 /*-----------------------------------------------------------------*/
2078 /* geniCodeSubtract - generates code for subtraction */
2079 /*-----------------------------------------------------------------*/
2081 geniCodeSubtract (operand * left, operand * right)
2088 /* if they both pointers then */
2089 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2090 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2091 return geniCodePtrPtrSubtract (left, right);
2093 /* if they are both literal then we know the result */
2094 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2095 && left->isLiteral && right->isLiteral)
2096 return operandFromValue (valMinus (left->operand.valOperand,
2097 right->operand.valOperand));
2099 /* if left is an array or pointer */
2100 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2102 isarray = left->isaddr;
2103 right = geniCodeMultiply (right,
2104 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2105 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2108 { /* make them the same size */
2109 resType = usualBinaryConversions (&left, &right);
2112 ic = newiCode ('-', left, right);
2114 IC_RESULT (ic) = newiTempOperand (resType, 1);
2115 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2117 /* if left or right is a float */
2118 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2122 return IC_RESULT (ic);
2125 /*-----------------------------------------------------------------*/
2126 /* geniCodeAdd - generates iCode for addition */
2127 /*-----------------------------------------------------------------*/
2129 geniCodeAdd (operand * left, operand * right, int lvl)
2137 /* if the right side is LITERAL zero */
2138 /* return the left side */
2139 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2142 /* if left is literal zero return right */
2143 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2146 /* if left is a pointer then size */
2147 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2149 isarray = left->isaddr;
2150 // there is no need to multiply with 1
2151 if (getSize(ltype->next)!=1) {
2152 size = operandFromLit (getSize (ltype->next));
2153 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2155 resType = copyLinkChain (ltype);
2158 { // make them the same size
2159 resType = usualBinaryConversions (&left, &right);
2162 /* if they are both literals then we know */
2163 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2164 && left->isLiteral && right->isLiteral)
2165 return operandFromValue (valPlus (valFromType (letype),
2166 valFromType (retype)));
2168 ic = newiCode ('+', left, right);
2170 IC_RESULT (ic) = newiTempOperand (resType, 1);
2171 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2173 /* if left or right is a float then support
2175 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2180 return IC_RESULT (ic);
2184 /*-----------------------------------------------------------------*/
2185 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2186 /*-----------------------------------------------------------------*/
2188 aggrToPtr (sym_link * type, bool force)
2193 if (IS_PTR (type) && !force)
2196 etype = getSpec (type);
2197 ptype = newLink (DECLARATOR);
2201 /* set the pointer depending on the storage class */
2202 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2206 /*-----------------------------------------------------------------*/
2207 /* geniCodeArray2Ptr - array to pointer */
2208 /*-----------------------------------------------------------------*/
2210 geniCodeArray2Ptr (operand * op)
2212 sym_link *optype = operandType (op);
2213 sym_link *opetype = getSpec (optype);
2215 /* set the pointer depending on the storage class */
2216 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2223 /*-----------------------------------------------------------------*/
2224 /* geniCodeArray - array access */
2225 /*-----------------------------------------------------------------*/
2227 geniCodeArray (operand * left, operand * right,int lvl)
2230 sym_link *ltype = operandType (left);
2234 if (IS_PTR (ltype->next) && left->isaddr)
2236 left = geniCodeRValue (left, FALSE);
2238 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2241 right = geniCodeMultiply (right,
2242 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2244 /* we can check for limits here */
2245 if (isOperandLiteral (right) &&
2248 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2250 werror (E_ARRAY_BOUND);
2251 right = operandFromLit (0);
2254 ic = newiCode ('+', left, right);
2256 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2257 !IS_AGGREGATE (ltype->next) &&
2258 !IS_PTR (ltype->next))
2259 ? ltype : ltype->next), 0);
2261 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2263 return IC_RESULT (ic);
2266 /*-----------------------------------------------------------------*/
2267 /* geniCodeStruct - generates intermediate code for structres */
2268 /*-----------------------------------------------------------------*/
2270 geniCodeStruct (operand * left, operand * right, bool islval)
2273 sym_link *type = operandType (left);
2274 sym_link *etype = getSpec (type);
2276 symbol *element = getStructElement (SPEC_STRUCT (etype),
2277 right->operand.symOperand);
2279 wassert(IS_SYMOP(right));
2281 /* add the offset */
2282 ic = newiCode ('+', left, operandFromLit (element->offset));
2284 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2286 /* preserve the storage & output class of the struct */
2287 /* as well as the volatile attribute */
2288 retype = getSpec (operandType (IC_RESULT (ic)));
2289 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2290 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2291 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2292 SPEC_CONST (retype) |= SPEC_CONST (etype);
2294 if (IS_PTR (element->type))
2295 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2297 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2300 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2303 /*-----------------------------------------------------------------*/
2304 /* geniCodePostInc - generate int code for Post increment */
2305 /*-----------------------------------------------------------------*/
2307 geniCodePostInc (operand * op)
2311 sym_link *optype = operandType (op);
2313 operand *rv = (IS_ITEMP (op) ?
2314 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2316 sym_link *rvtype = operandType (rv);
2319 /* if this is not an address we have trouble */
2322 werror (E_LVALUE_REQUIRED, "++");
2326 rOp = newiTempOperand (rvtype, 0);
2327 OP_SYMBOL(rOp)->noSpilLoc = 1;
2330 OP_SYMBOL(rv)->noSpilLoc = 1;
2332 geniCodeAssign (rOp, rv, 0);
2334 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2335 if (IS_FLOAT (rvtype))
2336 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2338 ic = newiCode ('+', rv, operandFromLit (size));
2340 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2343 geniCodeAssign (op, result, 0);
2349 /*-----------------------------------------------------------------*/
2350 /* geniCodePreInc - generate code for preIncrement */
2351 /*-----------------------------------------------------------------*/
2353 geniCodePreInc (operand * op)
2356 sym_link *optype = operandType (op);
2357 operand *rop = (IS_ITEMP (op) ?
2358 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2360 sym_link *roptype = operandType (rop);
2366 werror (E_LVALUE_REQUIRED, "++");
2371 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2372 if (IS_FLOAT (roptype))
2373 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2375 ic = newiCode ('+', rop, operandFromLit (size));
2376 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2380 return geniCodeAssign (op, result, 0);
2383 /*-----------------------------------------------------------------*/
2384 /* geniCodePostDec - generates code for Post decrement */
2385 /*-----------------------------------------------------------------*/
2387 geniCodePostDec (operand * op)
2391 sym_link *optype = operandType (op);
2393 operand *rv = (IS_ITEMP (op) ?
2394 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2396 sym_link *rvtype = operandType (rv);
2399 /* if this is not an address we have trouble */
2402 werror (E_LVALUE_REQUIRED, "--");
2406 rOp = newiTempOperand (rvtype, 0);
2407 OP_SYMBOL(rOp)->noSpilLoc = 1;
2410 OP_SYMBOL(rv)->noSpilLoc = 1;
2412 geniCodeAssign (rOp, rv, 0);
2414 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2415 if (IS_FLOAT (rvtype))
2416 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2418 ic = newiCode ('-', rv, operandFromLit (size));
2420 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2423 geniCodeAssign (op, result, 0);
2429 /*-----------------------------------------------------------------*/
2430 /* geniCodePreDec - generate code for pre decrement */
2431 /*-----------------------------------------------------------------*/
2433 geniCodePreDec (operand * op)
2436 sym_link *optype = operandType (op);
2437 operand *rop = (IS_ITEMP (op) ?
2438 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2440 sym_link *roptype = operandType (rop);
2446 werror (E_LVALUE_REQUIRED, "--");
2451 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2452 if (IS_FLOAT (roptype))
2453 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2455 ic = newiCode ('-', rop, operandFromLit (size));
2456 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2460 return geniCodeAssign (op, result, 0);
2464 /*-----------------------------------------------------------------*/
2465 /* geniCodeBitwise - gen int code for bitWise operators */
2466 /*-----------------------------------------------------------------*/
2468 geniCodeBitwise (operand * left, operand * right,
2469 int oper, sym_link * resType)
2473 left = geniCodeCast (resType, left, TRUE);
2474 right = geniCodeCast (resType, right, TRUE);
2476 ic = newiCode (oper, left, right);
2477 IC_RESULT (ic) = newiTempOperand (resType, 0);
2480 return IC_RESULT (ic);
2483 /*-----------------------------------------------------------------*/
2484 /* geniCodeAddressOf - gens icode for '&' address of operator */
2485 /*-----------------------------------------------------------------*/
2487 geniCodeAddressOf (operand * op)
2491 sym_link *optype = operandType (op);
2492 sym_link *opetype = getSpec (optype);
2494 /* lvalue check already done in decorateType */
2495 /* this must be a lvalue */
2496 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2497 /* werror (E_LVALUE_REQUIRED,"&"); */
2501 p = newLink (DECLARATOR);
2503 /* set the pointer depending on the storage class */
2504 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2506 p->next = copyLinkChain (optype);
2508 /* if already a temp */
2511 setOperandType (op, p);
2516 /* other wise make this of the type coming in */
2517 ic = newiCode (ADDRESS_OF, op, NULL);
2518 IC_RESULT (ic) = newiTempOperand (p, 1);
2519 IC_RESULT (ic)->isaddr = 0;
2521 return IC_RESULT (ic);
2523 /*-----------------------------------------------------------------*/
2524 /* setOClass - sets the output class depending on the pointer type */
2525 /*-----------------------------------------------------------------*/
2527 setOClass (sym_link * ptr, sym_link * spec)
2529 switch (DCL_TYPE (ptr))
2532 SPEC_OCLS (spec) = data;
2536 SPEC_OCLS (spec) = generic;
2540 SPEC_OCLS (spec) = xdata;
2544 SPEC_OCLS (spec) = code;
2548 SPEC_OCLS (spec) = idata;
2552 SPEC_OCLS (spec) = xstack;
2556 SPEC_OCLS (spec) = eeprom;
2565 /*-----------------------------------------------------------------*/
2566 /* geniCodeDerefPtr - dereference pointer with '*' */
2567 /*-----------------------------------------------------------------*/
2569 geniCodeDerefPtr (operand * op,int lvl)
2571 sym_link *rtype, *retype;
2572 sym_link *optype = operandType (op);
2574 // if this is an array then array access
2575 if (IS_ARRAY (optype)) {
2576 // don't worry, this will be optimized out later
2577 return geniCodeArray (op, operandFromLit (0), lvl);
2580 // just in case someone screws up
2581 wassert (IS_PTR (optype));
2583 if (IS_TRUE_SYMOP (op))
2586 op = geniCodeRValue (op, TRUE);
2589 /* now get rid of the pointer part */
2590 if (isLvaluereq(lvl) && IS_ITEMP (op))
2592 retype = getSpec (rtype = copyLinkChain (optype));
2596 retype = getSpec (rtype = copyLinkChain (optype->next));
2597 /* outputclass needs 2b updated */
2598 setOClass (optype, retype);
2601 op->isGptr = IS_GENPTR (optype);
2603 op->isaddr = (IS_PTR (rtype) ||
2604 IS_STRUCT (rtype) ||
2609 if (!isLvaluereq(lvl))
2610 op = geniCodeRValue (op, TRUE);
2612 setOperandType (op, rtype);
2617 /*-----------------------------------------------------------------*/
2618 /* geniCodeUnaryMinus - does a unary minus of the operand */
2619 /*-----------------------------------------------------------------*/
2621 geniCodeUnaryMinus (operand * op)
2624 sym_link *optype = operandType (op);
2626 if (IS_LITERAL (optype))
2627 return operandFromLit (-floatFromVal (op->operand.valOperand));
2629 ic = newiCode (UNARYMINUS, op, NULL);
2630 IC_RESULT (ic) = newiTempOperand (optype, 0);
2632 return IC_RESULT (ic);
2635 /*-----------------------------------------------------------------*/
2636 /* geniCodeLeftShift - gen i code for left shift */
2637 /*-----------------------------------------------------------------*/
2639 geniCodeLeftShift (operand * left, operand * right)
2643 ic = newiCode (LEFT_OP, left, right);
2644 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2646 return IC_RESULT (ic);
2649 /*-----------------------------------------------------------------*/
2650 /* geniCodeRightShift - gen i code for right shift */
2651 /*-----------------------------------------------------------------*/
2653 geniCodeRightShift (operand * left, operand * right)
2657 ic = newiCode (RIGHT_OP, left, right);
2658 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2660 return IC_RESULT (ic);
2663 /*-----------------------------------------------------------------*/
2664 /* geniCodeLogic- logic code */
2665 /*-----------------------------------------------------------------*/
2667 geniCodeLogic (operand * left, operand * right, int op)
2671 sym_link *rtype = operandType (right);
2672 sym_link *ltype = operandType (left);
2674 /* left is integral type and right is literal then
2675 check if the literal value is within bounds */
2676 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2678 checkConstantRange(ltype,
2679 OP_VALUE(right), "compare operation", 1);
2682 /* if one operand is a pointer and the other is a literal generic void pointer,
2683 change the type of the literal generic void pointer to match the other pointer */
2684 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2685 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2687 /* find left's definition */
2688 ic = (iCode *) setFirstItem (iCodeChain);
2691 if (((ic->op == CAST) || (ic->op == '='))
2692 && isOperandEqual(left, IC_RESULT (ic)))
2695 ic = setNextItem (iCodeChain);
2697 /* if casting literal to generic pointer, then cast to rtype instead */
2698 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2700 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2701 ltype = operandType(left);
2704 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2705 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2707 /* find right's definition */
2708 ic = (iCode *) setFirstItem (iCodeChain);
2711 if (((ic->op == CAST) || (ic->op == '='))
2712 && isOperandEqual(right, IC_RESULT (ic)))
2715 ic = setNextItem (iCodeChain);
2717 /* if casting literal to generic pointer, then cast to rtype instead */
2718 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2720 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2721 rtype = operandType(right);
2725 ctype = usualBinaryConversions (&left, &right);
2727 ic = newiCode (op, left, right);
2728 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2730 /* if comparing float
2731 and not a '==' || '!=' || '&&' || '||' (these
2733 if (IS_FLOAT(ctype) &&
2741 return IC_RESULT (ic);
2744 /*-----------------------------------------------------------------*/
2745 /* geniCodeUnary - for a a generic unary operation */
2746 /*-----------------------------------------------------------------*/
2748 geniCodeUnary (operand * op, int oper)
2750 iCode *ic = newiCode (oper, op, NULL);
2752 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2754 return IC_RESULT (ic);
2757 /*-----------------------------------------------------------------*/
2758 /* geniCodeConditional - geniCode for '?' ':' operation */
2759 /*-----------------------------------------------------------------*/
2761 geniCodeConditional (ast * tree,int lvl)
2764 symbol *falseLabel = newiTempLabel (NULL);
2765 symbol *exitLabel = newiTempLabel (NULL);
2766 operand *cond = ast2iCode (tree->left,lvl+1);
2767 operand *true, *false, *result;
2769 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2773 true = ast2iCode (tree->right->left,lvl+1);
2775 /* move the value to a new Operand */
2776 result = newiTempOperand (tree->right->ftype, 0);
2777 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2779 /* generate an unconditional goto */
2780 geniCodeGoto (exitLabel);
2782 /* now for the right side */
2783 geniCodeLabel (falseLabel);
2785 false = ast2iCode (tree->right->right,lvl+1);
2786 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2788 /* create the exit label */
2789 geniCodeLabel (exitLabel);
2794 /*-----------------------------------------------------------------*/
2795 /* geniCodeAssign - generate code for assignment */
2796 /*-----------------------------------------------------------------*/
2798 geniCodeAssign (operand * left, operand * right, int nosupdate)
2801 sym_link *ltype = operandType (left);
2802 sym_link *rtype = operandType (right);
2804 if (!left->isaddr && !IS_ITEMP (left))
2806 werror (E_LVALUE_REQUIRED, "assignment");
2810 /* left is integral type and right is literal then
2811 check if the literal value is within bounds */
2812 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2814 checkConstantRange(ltype,
2815 OP_VALUE(right), "= operation", 0);
2818 /* if the left & right type don't exactly match */
2819 /* if pointer set then make sure the check is
2820 done with the type & not the pointer */
2821 /* then cast rights type to left */
2823 /* first check the type for pointer assignement */
2824 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2825 compareType (ltype, rtype) <= 0)
2827 if (compareType (ltype->next, rtype) < 0)
2828 right = geniCodeCast (ltype->next, right, TRUE);
2830 else if (compareType (ltype, rtype) < 0)
2831 right = geniCodeCast (ltype, right, TRUE);
2833 /* if left is a true symbol & ! volatile
2834 create an assignment to temporary for
2835 the right & then assign this temporary
2836 to the symbol this is SSA . isn't it simple
2837 and folks have published mountains of paper on it */
2838 if (IS_TRUE_SYMOP (left) &&
2839 !isOperandVolatile (left, FALSE) &&
2840 isOperandGlobal (left))
2844 if (IS_TRUE_SYMOP (right))
2845 sym = OP_SYMBOL (right);
2846 ic = newiCode ('=', NULL, right);
2847 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2848 SPIL_LOC (right) = sym;
2852 ic = newiCode ('=', NULL, right);
2853 IC_RESULT (ic) = left;
2856 /* if left isgptr flag is set then support
2857 routine will be required */
2861 ic->nosupdate = nosupdate;
2865 /*-----------------------------------------------------------------*/
2866 /* geniCodeDummyRead - generate code for dummy read */
2867 /*-----------------------------------------------------------------*/
2869 geniCodeDummyRead (operand * op)
2872 sym_link *type = operandType (op);
2874 if (!IS_VOLATILE(type))
2877 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2883 /*-----------------------------------------------------------------*/
2884 /* geniCodeSEParms - generate code for side effecting fcalls */
2885 /*-----------------------------------------------------------------*/
2887 geniCodeSEParms (ast * parms,int lvl)
2892 if (parms->type == EX_OP && parms->opval.op == PARAM)
2894 geniCodeSEParms (parms->left,lvl);
2895 geniCodeSEParms (parms->right,lvl);
2899 /* hack don't like this but too lazy to think of
2901 if (IS_ADDRESS_OF_OP (parms))
2902 parms->left->lvalue = 1;
2904 if (IS_CAST_OP (parms) &&
2905 IS_PTR (parms->ftype) &&
2906 IS_ADDRESS_OF_OP (parms->right))
2907 parms->right->left->lvalue = 1;
2909 parms->opval.oprnd =
2910 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2912 parms->type = EX_OPERAND;
2913 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2914 SPEC_ARGREG(parms->ftype);
2917 /*-----------------------------------------------------------------*/
2918 /* geniCodeParms - generates parameters */
2919 /*-----------------------------------------------------------------*/
2921 geniCodeParms (ast * parms, value *argVals, int *stack,
2922 sym_link * fetype, symbol * func,int lvl)
2930 if (argVals==NULL) {
2932 argVals=FUNC_ARGS(func->type);
2935 /* if this is a param node then do the left & right */
2936 if (parms->type == EX_OP && parms->opval.op == PARAM)
2938 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2939 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2943 /* get the parameter value */
2944 if (parms->type == EX_OPERAND)
2945 pval = parms->opval.oprnd;
2948 /* maybe this else should go away ?? */
2949 /* hack don't like this but too lazy to think of
2951 if (IS_ADDRESS_OF_OP (parms))
2952 parms->left->lvalue = 1;
2954 if (IS_CAST_OP (parms) &&
2955 IS_PTR (parms->ftype) &&
2956 IS_ADDRESS_OF_OP (parms->right))
2957 parms->right->left->lvalue = 1;
2959 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2962 /* if register parm then make it a send */
2963 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2964 IFFUNC_ISBUILTIN(func->type))
2966 ic = newiCode (SEND, pval, NULL);
2967 ic->argreg = SPEC_ARGREG(parms->etype);
2968 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2973 /* now decide whether to push or assign */
2974 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2978 operand *top = operandFromSymbol (argVals->sym);
2979 /* clear useDef and other bitVectors */
2980 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
2981 geniCodeAssign (top, pval, 1);
2985 sym_link *p = operandType (pval);
2987 ic = newiCode (IPUSH, pval, NULL);
2989 /* update the stack adjustment */
2990 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2995 argVals=argVals->next;
2999 /*-----------------------------------------------------------------*/
3000 /* geniCodeCall - generates temp code for calling */
3001 /*-----------------------------------------------------------------*/
3003 geniCodeCall (operand * left, ast * parms,int lvl)
3007 sym_link *type, *etype;
3010 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3011 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3012 werror (E_FUNCTION_EXPECTED);
3016 /* take care of parameters with side-effecting
3017 function calls in them, this is required to take care
3018 of overlaying function parameters */
3019 geniCodeSEParms (parms,lvl);
3021 /* first the parameters */
3022 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3024 /* now call : if symbol then pcall */
3025 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3026 ic = newiCode (PCALL, left, NULL);
3028 ic = newiCode (CALL, left, NULL);
3031 type = copyLinkChain (operandType (left)->next);
3032 etype = getSpec (type);
3033 SPEC_EXTR (etype) = 0;
3034 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3038 /* stack adjustment after call */
3039 ic->parmBytes = stack;
3044 /*-----------------------------------------------------------------*/
3045 /* geniCodeReceive - generate intermediate code for "receive" */
3046 /*-----------------------------------------------------------------*/
3048 geniCodeReceive (value * args)
3050 /* for all arguments that are passed in registers */
3054 if (IS_REGPARM (args->etype))
3056 operand *opr = operandFromValue (args);
3058 symbol *sym = OP_SYMBOL (opr);
3061 /* we will use it after all optimizations
3062 and before liveRange calculation */
3063 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3066 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
3067 options.stackAuto == 0 &&
3068 (!(options.model == MODEL_FLAT24)) )
3073 opl = newiTempOperand (args->type, 0);
3075 sym->reqv->key = sym->key;
3076 OP_SYMBOL (sym->reqv)->key = sym->key;
3077 OP_SYMBOL (sym->reqv)->isreqv = 1;
3078 OP_SYMBOL (sym->reqv)->islocal = 0;
3079 SPIL_LOC (sym->reqv) = sym;
3083 ic = newiCode (RECEIVE, NULL, NULL);
3084 ic->argreg = SPEC_ARGREG(args->etype);
3086 currFunc->recvSize = getSize (sym->type);
3089 IC_RESULT (ic) = opr;
3097 /*-----------------------------------------------------------------*/
3098 /* geniCodeFunctionBody - create the function body */
3099 /*-----------------------------------------------------------------*/
3101 geniCodeFunctionBody (ast * tree,int lvl)
3108 /* reset the auto generation */
3114 func = ast2iCode (tree->left,lvl+1);
3115 fetype = getSpec (operandType (func));
3117 savelineno = lineno;
3118 lineno = OP_SYMBOL (func)->lineDef;
3119 /* create an entry label */
3120 geniCodeLabel (entryLabel);
3121 lineno = savelineno;
3123 /* create a proc icode */
3124 ic = newiCode (FUNCTION, func, NULL);
3125 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3129 /* for all parameters that are passed
3130 on registers add a "receive" */
3131 geniCodeReceive (tree->values.args);
3133 /* generate code for the body */
3134 ast2iCode (tree->right,lvl+1);
3136 /* create a label for return */
3137 geniCodeLabel (returnLabel);
3139 /* now generate the end proc */
3140 ic = newiCode (ENDFUNCTION, func, NULL);
3145 /*-----------------------------------------------------------------*/
3146 /* geniCodeReturn - gen icode for 'return' statement */
3147 /*-----------------------------------------------------------------*/
3149 geniCodeReturn (operand * op)
3153 /* if the operand is present force an rvalue */
3155 op = geniCodeRValue (op, FALSE);
3157 ic = newiCode (RETURN, op, NULL);
3161 /*-----------------------------------------------------------------*/
3162 /* geniCodeIfx - generates code for extended if statement */
3163 /*-----------------------------------------------------------------*/
3165 geniCodeIfx (ast * tree,int lvl)
3168 operand *condition = ast2iCode (tree->left,lvl+1);
3171 /* if condition is null then exit */
3175 condition = geniCodeRValue (condition, FALSE);
3177 cetype = getSpec (operandType (condition));
3178 /* if the condition is a literal */
3179 if (IS_LITERAL (cetype))
3181 if (floatFromVal (condition->operand.valOperand))
3183 if (tree->trueLabel)
3184 geniCodeGoto (tree->trueLabel);
3190 if (tree->falseLabel)
3191 geniCodeGoto (tree->falseLabel);
3198 if (tree->trueLabel)
3200 ic = newiCodeCondition (condition,
3205 if (tree->falseLabel)
3206 geniCodeGoto (tree->falseLabel);
3210 ic = newiCodeCondition (condition,
3217 ast2iCode (tree->right,lvl+1);
3220 /*-----------------------------------------------------------------*/
3221 /* geniCodeJumpTable - tries to create a jump table for switch */
3222 /*-----------------------------------------------------------------*/
3224 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3226 int min = 0, max = 0, t, cnt = 0;
3232 int needRangeCheck = !optimize.noJTabBoundary
3233 || tree->values.switchVals.swDefault;
3235 if (!tree || !caseVals)
3238 /* the criteria for creating a jump table is */
3239 /* all integer numbers between the maximum & minimum must */
3240 /* be present , the maximum value should not exceed 255 */
3241 min = max = (int) floatFromVal (vch = caseVals);
3242 SNPRINTF (buffer, sizeof(buffer),
3244 tree->values.switchVals.swNum,
3246 addSet (&labels, newiTempLabel (buffer));
3248 /* if there is only one case value then no need */
3249 if (!(vch = vch->next))
3254 if (((t = (int) floatFromVal (vch)) - max) != 1)
3256 SNPRINTF (buffer, sizeof(buffer),
3258 tree->values.switchVals.swNum,
3260 addSet (&labels, newiTempLabel (buffer));
3266 /* if the number of case statements <= 2 then */
3267 /* it is not economical to create the jump table */
3268 /* since two compares are needed for boundary conditions */
3269 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3272 if (tree->values.switchVals.swDefault)
3274 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3278 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3282 falseLabel = newiTempLabel (buffer);
3284 /* so we can create a jumptable */
3285 /* first we rule out the boundary conditions */
3286 /* if only optimization says so */
3289 sym_link *cetype = getSpec (operandType (cond));
3290 /* no need to check the lower bound if
3291 the condition is unsigned & minimum value is zero */
3292 if (!(min == 0 && SPEC_USIGN (cetype)))
3294 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3295 ic = newiCodeCondition (boundary, falseLabel, NULL);
3299 /* now for upper bounds */
3300 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3301 ic = newiCodeCondition (boundary, falseLabel, NULL);
3305 /* if the min is not zero then we no make it zero */
3308 cond = geniCodeSubtract (cond, operandFromLit (min));
3309 if (!IS_LITERAL(getSpec(operandType(cond))))
3310 setOperandType (cond, UCHARTYPE);
3313 /* now create the jumptable */
3314 ic = newiCode (JUMPTABLE, NULL, NULL);
3315 IC_JTCOND (ic) = cond;
3316 IC_JTLABELS (ic) = labels;
3321 /*-----------------------------------------------------------------*/
3322 /* geniCodeSwitch - changes a switch to a if statement */
3323 /*-----------------------------------------------------------------*/
3325 geniCodeSwitch (ast * tree,int lvl)
3328 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3329 value *caseVals = tree->values.switchVals.swVals;
3330 symbol *trueLabel, *falseLabel;
3332 /* If the condition is a literal, then just jump to the */
3333 /* appropriate case label. */
3334 if (IS_LITERAL(getSpec(operandType(cond))))
3336 int switchVal, caseVal;
3338 switchVal = (int) floatFromVal (cond->operand.valOperand);
3341 caseVal = (int) floatFromVal (caseVals);
3342 if (caseVal == switchVal)
3344 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3345 tree->values.switchVals.swNum, caseVal);
3346 trueLabel = newiTempLabel (buffer);
3347 geniCodeGoto (trueLabel);
3350 caseVals = caseVals->next;
3352 goto defaultOrBreak;
3355 /* if we can make this a jump table */
3356 if (geniCodeJumpTable (cond, caseVals, tree))
3357 goto jumpTable; /* no need for the comparison */
3359 /* for the cases defined do */
3363 operand *compare = geniCodeLogic (cond,
3364 operandFromValue (caseVals),
3367 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3368 tree->values.switchVals.swNum,
3369 (int) floatFromVal (caseVals));
3370 trueLabel = newiTempLabel (buffer);
3372 ic = newiCodeCondition (compare, trueLabel, NULL);
3374 caseVals = caseVals->next;
3379 /* if default is present then goto break else break */
3380 if (tree->values.switchVals.swDefault)
3382 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3386 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3389 falseLabel = newiTempLabel (buffer);
3390 geniCodeGoto (falseLabel);
3393 ast2iCode (tree->right,lvl+1);
3396 /*-----------------------------------------------------------------*/
3397 /* geniCodeInline - intermediate code for inline assembler */
3398 /*-----------------------------------------------------------------*/
3400 geniCodeInline (ast * tree)
3404 ic = newiCode (INLINEASM, NULL, NULL);
3405 IC_INLINE (ic) = tree->values.inlineasm;
3409 /*-----------------------------------------------------------------*/
3410 /* geniCodeArrayInit - intermediate code for array initializer */
3411 /*-----------------------------------------------------------------*/
3413 geniCodeArrayInit (ast * tree, operand *array)
3417 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3418 ic = newiCode (ARRAYINIT, array, NULL);
3419 IC_ARRAYILIST (ic) = tree->values.constlist;
3421 operand *left=newOperand(), *right=newOperand();
3422 left->type=right->type=SYMBOL;
3423 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3424 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3425 ic = newiCode (ARRAYINIT, left, right);
3430 /*-----------------------------------------------------------------*/
3431 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3432 /* particular case. Ie : assigning or dereferencing array or ptr */
3433 /*-----------------------------------------------------------------*/
3434 set * lvaluereqSet = NULL;
3435 typedef struct lvalItem
3442 /*-----------------------------------------------------------------*/
3443 /* addLvaluereq - add a flag for lvalreq for current ast level */
3444 /*-----------------------------------------------------------------*/
3445 void addLvaluereq(int lvl)
3447 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3450 addSetHead(&lvaluereqSet,lpItem);
3453 /*-----------------------------------------------------------------*/
3454 /* delLvaluereq - del a flag for lvalreq for current ast level */
3455 /*-----------------------------------------------------------------*/
3459 lpItem = getSet(&lvaluereqSet);
3460 if(lpItem) Safe_free(lpItem);
3462 /*-----------------------------------------------------------------*/
3463 /* clearLvaluereq - clear lvalreq flag */
3464 /*-----------------------------------------------------------------*/
3465 void clearLvaluereq()
3468 lpItem = peekSet(lvaluereqSet);
3469 if(lpItem) lpItem->req = 0;
3471 /*-----------------------------------------------------------------*/
3472 /* getLvaluereq - get the last lvalreq level */
3473 /*-----------------------------------------------------------------*/
3474 int getLvaluereqLvl()
3477 lpItem = peekSet(lvaluereqSet);
3478 if(lpItem) return lpItem->lvl;
3481 /*-----------------------------------------------------------------*/
3482 /* isLvaluereq - is lvalreq valid for this level ? */
3483 /*-----------------------------------------------------------------*/
3484 int isLvaluereq(int lvl)
3487 lpItem = peekSet(lvaluereqSet);
3488 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3492 /*-----------------------------------------------------------------*/
3493 /* ast2iCode - creates an icodeList from an ast */
3494 /*-----------------------------------------------------------------*/
3496 ast2iCode (ast * tree,int lvl)
3498 operand *left = NULL;
3499 operand *right = NULL;
3503 /* set the global variables for filename & line number */
3505 filename = tree->filename;
3507 lineno = tree->lineno;
3509 block = tree->block;
3511 scopeLevel = tree->level;
3513 if (tree->type == EX_VALUE)
3514 return operandFromValue (tree->opval.val);
3516 if (tree->type == EX_LINK)
3517 return operandFromLink (tree->opval.lnk);
3519 /* if we find a nullop */
3520 if (tree->type == EX_OP &&
3521 (tree->opval.op == NULLOP ||
3522 tree->opval.op == BLOCK))
3524 if (tree->left && tree->left->type == EX_VALUE)
3525 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3527 ast2iCode (tree->left,lvl+1);
3528 if (tree->right && tree->right->type == EX_VALUE)
3529 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3531 ast2iCode (tree->right,lvl+1);
3535 /* special cases for not evaluating */
3536 if (tree->opval.op != ':' &&
3537 tree->opval.op != '?' &&
3538 tree->opval.op != CALL &&
3539 tree->opval.op != IFX &&
3540 tree->opval.op != LABEL &&
3541 tree->opval.op != GOTO &&
3542 tree->opval.op != SWITCH &&
3543 tree->opval.op != FUNCTION &&
3544 tree->opval.op != INLINEASM)
3547 if (IS_ASSIGN_OP (tree->opval.op) ||
3548 IS_DEREF_OP (tree) ||
3549 (tree->opval.op == '&' && !tree->right) ||
3550 tree->opval.op == PTR_OP)
3553 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3554 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3557 left = operandFromAst (tree->left,lvl);
3559 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3560 left = geniCodeRValue (left, TRUE);
3564 left = operandFromAst (tree->left,lvl);
3566 if (tree->opval.op == INC_OP ||
3567 tree->opval.op == DEC_OP)
3570 right = operandFromAst (tree->right,lvl);
3575 right = operandFromAst (tree->right,lvl);
3579 /* now depending on the type of operand */
3580 /* this will be a biggy */
3581 switch (tree->opval.op)
3584 case '[': /* array operation */
3586 //sym_link *ltype = operandType (left);
3587 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3588 left = geniCodeRValue (left, FALSE);
3589 right = geniCodeRValue (right, TRUE);
3592 return geniCodeArray (left, right,lvl);
3594 case '.': /* structure dereference */
3595 if (IS_PTR (operandType (left)))
3596 left = geniCodeRValue (left, TRUE);
3598 left = geniCodeRValue (left, FALSE);
3600 return geniCodeStruct (left, right, tree->lvalue);
3602 case PTR_OP: /* structure pointer dereference */
3605 pType = operandType (left);
3606 left = geniCodeRValue (left, TRUE);
3608 setOClass (pType, getSpec (operandType (left)));
3611 return geniCodeStruct (left, right, tree->lvalue);
3613 case INC_OP: /* increment operator */
3615 return geniCodePostInc (left);
3617 return geniCodePreInc (right);
3619 case DEC_OP: /* decrement operator */
3621 return geniCodePostDec (left);
3623 return geniCodePreDec (right);
3625 case '&': /* bitwise and or address of operator */
3627 { /* this is a bitwise operator */
3628 left = geniCodeRValue (left, FALSE);
3629 right = geniCodeRValue (right, FALSE);
3630 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3633 return geniCodeAddressOf (left);
3635 case '|': /* bitwise or & xor */
3637 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3638 geniCodeRValue (right, FALSE),
3643 return geniCodeDivision (geniCodeRValue (left, FALSE),
3644 geniCodeRValue (right, FALSE));
3647 return geniCodeModulus (geniCodeRValue (left, FALSE),
3648 geniCodeRValue (right, FALSE));
3651 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3652 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3654 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3658 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3659 geniCodeRValue (right, FALSE));
3661 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3665 return geniCodeAdd (geniCodeRValue (left, FALSE),
3666 geniCodeRValue (right, FALSE),lvl);
3668 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3671 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3672 geniCodeRValue (right, FALSE));
3675 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3676 geniCodeRValue (right, FALSE));
3678 #if 0 // this indeed needs a second thought
3682 // let's keep this simple: get the rvalue we need
3683 op=geniCodeRValue (right, FALSE);
3684 // now cast it to whatever we want
3685 op=geniCodeCast (operandType(left), op, FALSE);
3686 // if this is going to be used as an lvalue, make it so
3692 #else // bug #604575, is it a bug ????
3693 return geniCodeCast (operandType (left),
3694 geniCodeRValue (right, FALSE), FALSE);
3700 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3705 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3706 setOperandType (op, UCHARTYPE);
3717 /* different compilers (even different gccs) evaluate
3718 the two calls in a different order. to get the same
3719 result on all machines we've to specify a clear sequence.
3720 return geniCodeLogic (geniCodeRValue (left, FALSE),
3721 geniCodeRValue (right, FALSE),
3725 operand *leftOp, *rightOp;
3727 rightOp = geniCodeRValue (right, FALSE);
3728 leftOp = geniCodeRValue (left , FALSE);
3730 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3733 return geniCodeConditional (tree,lvl);
3736 return operandFromLit (getSize (tree->right->ftype));
3740 sym_link *rtype = operandType (right);
3741 sym_link *ltype = operandType (left);
3742 if (IS_PTR (rtype) && IS_ITEMP (right)
3743 && right->isaddr && compareType (rtype->next, ltype) == 1)
3744 right = geniCodeRValue (right, TRUE);
3746 right = geniCodeRValue (right, FALSE);
3748 geniCodeAssign (left, right, 0);
3753 geniCodeAssign (left,
3754 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3756 geniCodeRValue (right, FALSE),FALSE), 0);
3760 geniCodeAssign (left,
3761 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3763 geniCodeRValue (right, FALSE)), 0);
3766 geniCodeAssign (left,
3767 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3769 geniCodeRValue (right, FALSE)), 0);
3772 sym_link *rtype = operandType (right);
3773 sym_link *ltype = operandType (left);
3774 if (IS_PTR (rtype) && IS_ITEMP (right)
3775 && right->isaddr && compareType (rtype->next, ltype) == 1)
3776 right = geniCodeRValue (right, TRUE);
3778 right = geniCodeRValue (right, FALSE);
3781 return geniCodeAssign (left,
3782 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3788 sym_link *rtype = operandType (right);
3789 sym_link *ltype = operandType (left);
3790 if (IS_PTR (rtype) && IS_ITEMP (right)
3791 && right->isaddr && compareType (rtype->next, ltype) == 1)
3793 right = geniCodeRValue (right, TRUE);
3797 right = geniCodeRValue (right, FALSE);
3800 geniCodeAssign (left,
3801 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3807 geniCodeAssign (left,
3808 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3810 geniCodeRValue (right, FALSE)), 0);
3813 geniCodeAssign (left,
3814 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3816 geniCodeRValue (right, FALSE)), 0);
3819 geniCodeAssign (left,
3820 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3822 geniCodeRValue (right, FALSE),
3824 operandType (left)), 0);
3827 geniCodeAssign (left,
3828 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3830 geniCodeRValue (right, FALSE),
3832 operandType (left)), 0);
3835 geniCodeAssign (left,
3836 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3838 geniCodeRValue (right, FALSE),
3840 operandType (left)), 0);
3842 return geniCodeRValue (right, FALSE);
3845 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3848 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3849 return ast2iCode (tree->right,lvl+1);
3852 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3853 return ast2iCode (tree->right,lvl+1);
3856 geniCodeFunctionBody (tree,lvl);
3860 geniCodeReturn (right);
3864 geniCodeIfx (tree,lvl);
3868 geniCodeSwitch (tree,lvl);
3872 geniCodeInline (tree);
3876 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3883 /*-----------------------------------------------------------------*/
3884 /* reverseICChain - gets from the list and creates a linkedlist */
3885 /*-----------------------------------------------------------------*/
3892 while ((loop = getSet (&iCodeChain)))
3904 /*-----------------------------------------------------------------*/
3905 /* iCodeFromAst - given an ast will convert it to iCode */
3906 /*-----------------------------------------------------------------*/
3908 iCodeFromAst (ast * tree)
3910 returnLabel = newiTempLabel ("_return");
3911 entryLabel = newiTempLabel ("_entry");
3913 return reverseiCChain ();
3916 static const char *opTypeToStr(OPTYPE op)
3920 case SYMBOL: return "symbol";
3921 case VALUE: return "value";
3922 case TYPE: return "type";
3924 return "undefined type";
3928 operand *validateOpType(operand *op,
3935 if (op && op->type == type)
3940 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
3941 " expected %s, got %s\n",
3942 macro, args, file, line,
3943 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
3945 return op; // never reached, makes compiler happy.