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 (ul != (TYPE_UWORD) ul)
1100 else /* signed int */
1102 /* signed int is handled here in order to detect overflow */
1103 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1104 (TYPE_WORD) operandLitValue (right);
1106 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1107 if (l != (TYPE_WORD) l)
1112 /* all others go here: */
1113 retval = operandFromValue (valCastLiteral (type,
1114 operandLitValue (left) *
1115 operandLitValue (right)));
1118 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1120 werror (E_DIVIDE_BY_ZERO);
1125 retval = operandFromValue (valCastLiteral (type,
1126 operandLitValue (left) /
1127 operandLitValue (right)));
1130 if ((TYPE_UDWORD) operandLitValue (right) == 0) {
1131 werror (E_DIVIDE_BY_ZERO);
1136 if (SPEC_USIGN(let) || SPEC_USIGN(ret))
1137 /* one of the operands is unsigned */
1138 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1139 (TYPE_UDWORD) operandLitValue (right));
1141 /* both operands are signed */
1142 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1143 (TYPE_DWORD) operandLitValue (right));
1147 /* The number of left shifts is always unsigned. Signed doesn't make
1148 sense here. Shifting by a negative number is impossible. */
1149 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1150 (TYPE_UDWORD) operandLitValue (right));
1153 /* The number of right shifts is always unsigned. Signed doesn't make
1154 sense here. Shifting by a negative number is impossible. */
1155 if (SPEC_USIGN(let))
1156 /* unsigned: logic shift right */
1157 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1158 (TYPE_UDWORD) operandLitValue (right));
1160 /* signed: arithmetic shift right */
1161 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1162 (TYPE_UDWORD) operandLitValue (right));
1165 /* this op doesn't care about signedness */
1169 l = (TYPE_UDWORD) operandLitValue (left);
1170 if (SPEC_NOUN(OP_VALUE(left)->type) == V_CHAR)
1172 else if (!SPEC_LONG (OP_VALUE(left)->type))
1174 r = (TYPE_UDWORD) operandLitValue (right);
1175 if (SPEC_NOUN(OP_VALUE(right)->type) == V_CHAR)
1177 else if (!SPEC_LONG (OP_VALUE(right)->type))
1179 retval = operandFromLit (l == r);
1183 retval = operandFromLit (operandLitValue (left) <
1184 operandLitValue (right));
1187 retval = operandFromLit (operandLitValue (left) <=
1188 operandLitValue (right));
1191 retval = operandFromLit (operandLitValue (left) !=
1192 operandLitValue (right));
1195 retval = operandFromLit (operandLitValue (left) >
1196 operandLitValue (right));
1199 retval = operandFromLit (operandLitValue (left) >=
1200 operandLitValue (right));
1203 retval = operandFromValue (valCastLiteral (type,
1204 (TYPE_UDWORD)operandLitValue(left) &
1205 (TYPE_UDWORD)operandLitValue(right)));
1208 retval = operandFromValue (valCastLiteral (type,
1209 (TYPE_UDWORD)operandLitValue(left) |
1210 (TYPE_UDWORD)operandLitValue(right)));
1213 retval = operandFromValue (valCastLiteral (type,
1214 (TYPE_UDWORD)operandLitValue(left) ^
1215 (TYPE_UDWORD)operandLitValue(right)));
1218 retval = operandFromLit (operandLitValue (left) &&
1219 operandLitValue (right));
1222 retval = operandFromLit (operandLitValue (left) ||
1223 operandLitValue (right));
1227 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1229 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1235 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1237 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1243 retval = operandFromValue (valCastLiteral (type,
1244 -1 * operandLitValue (left)));
1248 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1252 retval = operandFromLit (!operandLitValue (left));
1256 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1257 " operandOperation invalid operator ");
1265 /*-----------------------------------------------------------------*/
1266 /* isOperandEqual - compares two operand & return 1 if they r = */
1267 /*-----------------------------------------------------------------*/
1269 isOperandEqual (operand * left, operand * right)
1271 /* if the pointers are equal then they are equal */
1275 /* if either of them null then false */
1276 if (!left || !right)
1279 if (left->type != right->type)
1282 if (IS_SYMOP (left) && IS_SYMOP (right))
1283 return left->key == right->key;
1285 /* if types are the same */
1289 return isSymbolEqual (left->operand.symOperand,
1290 right->operand.symOperand);
1292 return (floatFromVal (left->operand.valOperand) ==
1293 floatFromVal (right->operand.valOperand));
1295 if (compareType (left->operand.typeOperand,
1296 right->operand.typeOperand) == 1)
1303 /*-------------------------------------------------------------------*/
1304 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1305 /*-------------------------------------------------------------------*/
1307 isiCodeEqual (iCode * left, iCode * right)
1309 /* if the same pointer */
1313 /* if either of them null */
1314 if (!left || !right)
1317 /* if operand are the same */
1318 if (left->op == right->op)
1321 /* compare all the elements depending on type */
1322 if (left->op != IFX)
1324 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1326 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1332 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1334 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1336 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1345 /*-----------------------------------------------------------------*/
1346 /* newiTempFromOp - create a temp Operand with same attributes */
1347 /*-----------------------------------------------------------------*/
1349 newiTempFromOp (operand * op)
1359 nop = newiTempOperand (operandType (op), TRUE);
1360 nop->isaddr = op->isaddr;
1361 nop->isvolatile = op->isvolatile;
1362 nop->isGlobal = op->isGlobal;
1363 nop->isLiteral = op->isLiteral;
1364 nop->usesDefs = op->usesDefs;
1365 nop->isParm = op->isParm;
1369 /*-----------------------------------------------------------------*/
1370 /* operand from operand - creates an operand holder for the type */
1371 /*-----------------------------------------------------------------*/
1373 operandFromOperand (operand * op)
1379 nop = newOperand ();
1380 nop->type = op->type;
1381 nop->isaddr = op->isaddr;
1383 nop->isvolatile = op->isvolatile;
1384 nop->isGlobal = op->isGlobal;
1385 nop->isLiteral = op->isLiteral;
1386 nop->usesDefs = op->usesDefs;
1387 nop->isParm = op->isParm;
1392 nop->operand.symOperand = op->operand.symOperand;
1395 nop->operand.valOperand = op->operand.valOperand;
1398 nop->operand.typeOperand = op->operand.typeOperand;
1405 /*-----------------------------------------------------------------*/
1406 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1407 /*-----------------------------------------------------------------*/
1409 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1411 operand *nop = operandFromOperand (op);
1413 if (nop->type == SYMBOL)
1415 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1416 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1422 /*-----------------------------------------------------------------*/
1423 /* operandFromSymbol - creates an operand from a symbol */
1424 /*-----------------------------------------------------------------*/
1426 operandFromSymbol (symbol * sym)
1431 /* if the symbol's type is a literal */
1432 /* then it is an enumerator type */
1433 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1434 return operandFromValue (valFromType (sym->etype));
1437 sym->key = ++operandKey;
1439 /* if this an implicit variable, means struct/union */
1440 /* member so just return it */
1441 if (sym->implicit || IS_FUNC (sym->type))
1445 op->operand.symOperand = sym;
1447 op->isvolatile = isOperandVolatile (op, TRUE);
1448 op->isGlobal = isOperandGlobal (op);
1452 /* under the following conditions create a
1453 register equivalent for a local symbol */
1454 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1455 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1456 (!(options.model == MODEL_FLAT24)) ) &&
1457 options.stackAuto == 0)
1460 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1461 !IS_FUNC (sym->type) && /* not a function */
1462 !sym->_isparm && /* not a parameter */
1463 sym->level && /* is a local variable */
1464 !sym->addrtaken && /* whose address has not been taken */
1465 !sym->reqv && /* does not already have a reg equivalence */
1466 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1467 !IS_STATIC (sym->etype) && /* and not declared static */
1468 !sym->islbl && /* not a label */
1469 ok && /* farspace check */
1470 !IS_BITVAR (sym->etype) /* not a bit variable */
1474 /* we will use it after all optimizations
1475 and before liveRange calculation */
1476 sym->reqv = newiTempOperand (sym->type, 0);
1477 sym->reqv->key = sym->key;
1478 OP_SYMBOL (sym->reqv)->key = sym->key;
1479 OP_SYMBOL (sym->reqv)->isreqv = 1;
1480 OP_SYMBOL (sym->reqv)->islocal = 1;
1481 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1482 SPIL_LOC (sym->reqv) = sym;
1485 if (!IS_AGGREGATE (sym->type))
1489 op->operand.symOperand = sym;
1492 op->isvolatile = isOperandVolatile (op, TRUE);
1493 op->isGlobal = isOperandGlobal (op);
1494 op->isPtr = IS_PTR (operandType (op));
1495 op->isParm = sym->_isparm;
1500 /* itemp = &[_symbol] */
1502 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1503 IC_LEFT (ic)->type = SYMBOL;
1504 IC_LEFT (ic)->operand.symOperand = sym;
1505 IC_LEFT (ic)->key = sym->key;
1506 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1507 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1508 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1511 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1512 if (IS_ARRAY (sym->type))
1514 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1515 IC_RESULT (ic)->isaddr = 0;
1518 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1522 return IC_RESULT (ic);
1525 /*-----------------------------------------------------------------*/
1526 /* operandFromValue - creates an operand from value */
1527 /*-----------------------------------------------------------------*/
1529 operandFromValue (value * val)
1533 /* if this is a symbol then do the symbol thing */
1535 return operandFromSymbol (val->sym);
1537 /* this is not a symbol */
1540 op->operand.valOperand = val;
1541 op->isLiteral = isOperandLiteral (op);
1545 /*-----------------------------------------------------------------*/
1546 /* operandFromLink - operand from typeChain */
1547 /*-----------------------------------------------------------------*/
1549 operandFromLink (sym_link * type)
1553 /* operand from sym_link */
1559 op->operand.typeOperand = copyLinkChain (type);
1563 /*-----------------------------------------------------------------*/
1564 /* operandFromLit - makes an operand from a literal value */
1565 /*-----------------------------------------------------------------*/
1567 operandFromLit (double i)
1569 return operandFromValue (valueFromLit (i));
1572 /*-----------------------------------------------------------------*/
1573 /* operandFromAst - creates an operand from an ast */
1574 /*-----------------------------------------------------------------*/
1576 operandFromAst (ast * tree,int lvl)
1582 /* depending on type do */
1586 return ast2iCode (tree,lvl+1);
1590 return operandFromValue (tree->opval.val);
1594 return operandFromLink (tree->opval.lnk);
1601 /* Just to keep the compiler happy */
1602 return (operand *) 0;
1605 /*-----------------------------------------------------------------*/
1606 /* setOperandType - sets the operand's type to the given type */
1607 /*-----------------------------------------------------------------*/
1609 setOperandType (operand * op, sym_link * type)
1611 /* depending on the type of operand */
1616 op->operand.valOperand->etype =
1617 getSpec (op->operand.valOperand->type =
1618 copyLinkChain (type));
1622 if (op->operand.symOperand->isitmp)
1623 op->operand.symOperand->etype =
1624 getSpec (op->operand.symOperand->type =
1625 copyLinkChain (type));
1627 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1628 "attempt to modify type of source");
1632 op->operand.typeOperand = copyLinkChain (type);
1637 /*-----------------------------------------------------------------*/
1638 /* Get size in byte of ptr need to access an array */
1639 /*-----------------------------------------------------------------*/
1641 getArraySizePtr (operand * op)
1643 sym_link *ltype = operandType(op);
1647 int size = getSize(ltype);
1648 return(IS_GENPTR(ltype)?(size-1):size);
1653 sym_link *letype = getSpec(ltype);
1654 switch (PTR_TYPE (SPEC_OCLS (letype)))
1666 return (GPTRSIZE-1);
1675 /*-----------------------------------------------------------------*/
1676 /* perform "usual unary conversions" */
1677 /*-----------------------------------------------------------------*/
1679 usualUnaryConversions (operand * op)
1681 if (IS_INTEGRAL (operandType (op)))
1683 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1686 return geniCodeCast (INTTYPE, op, TRUE);
1692 /*-----------------------------------------------------------------*/
1693 /* perform "usual binary conversions" */
1694 /*-----------------------------------------------------------------*/
1696 usualBinaryConversions (operand ** op1, operand ** op2)
1699 sym_link *rtype = operandType (*op2);
1700 sym_link *ltype = operandType (*op1);
1702 ctype = computeType (ltype, rtype);
1704 *op1 = geniCodeCast (ctype, *op1, TRUE);
1705 *op2 = geniCodeCast (ctype, *op2, TRUE);
1710 /*-----------------------------------------------------------------*/
1711 /* geniCodeValueAtAddress - generate intermeditate code for value */
1713 /*-----------------------------------------------------------------*/
1715 geniCodeRValue (operand * op, bool force)
1718 sym_link *type = operandType (op);
1719 sym_link *etype = getSpec (type);
1721 /* if this is an array & already */
1722 /* an address then return this */
1723 if (IS_AGGREGATE (type) ||
1724 (IS_PTR (type) && !force && !op->isaddr))
1725 return operandFromOperand (op);
1727 /* if this is not an address then must be */
1728 /* rvalue already so return this one */
1732 /* if this is not a temp symbol then */
1733 if (!IS_ITEMP (op) &&
1735 !IN_FARSPACE (SPEC_OCLS (etype)))
1737 op = operandFromOperand (op);
1742 if (IS_SPEC (type) &&
1743 IS_TRUE_SYMOP (op) &&
1744 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1745 (options.model == MODEL_FLAT24) ))
1747 op = operandFromOperand (op);
1752 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1753 if (IS_PTR (type) && op->isaddr && force)
1756 type = copyLinkChain (type);
1758 IC_RESULT (ic) = newiTempOperand (type, 1);
1759 IC_RESULT (ic)->isaddr = 0;
1761 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1765 return IC_RESULT (ic);
1768 /*-----------------------------------------------------------------*/
1769 /* geniCodeCast - changes the value from one type to another */
1770 /*-----------------------------------------------------------------*/
1772 geniCodeCast (sym_link * type, operand * op, bool implicit)
1776 sym_link *opetype = getSpec (optype = operandType (op));
1780 /* one of them has size zero then error */
1781 if (IS_VOID (optype))
1783 werror (E_CAST_ZERO);
1787 /* if the operand is already the desired type then do nothing */
1788 if (compareType (type, optype) == 1)
1791 /* if this is a literal then just change the type & return */
1792 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1793 return operandFromValue (valCastLiteral (type,
1794 operandLitValue (op)));
1796 /* if casting to/from pointers, do some checking */
1797 if (IS_PTR(type)) { // to a pointer
1798 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1799 if (IS_INTEGRAL(optype)) {
1800 // maybe this is NULL, than it's ok.
1801 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1802 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1803 // no way to set the storage
1804 if (IS_LITERAL(optype)) {
1805 werror(E_LITERAL_GENERIC);
1808 werror(E_NONPTR2_GENPTR);
1811 } else if (implicit) {
1812 werror(W_INTEGRAL2PTR_NOCAST);
1817 // shouldn't do that with float, array or structure unless to void
1818 if (!IS_VOID(getSpec(type)) &&
1819 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1820 werror(E_INCOMPAT_TYPES);
1824 } else { // from a pointer to a pointer
1825 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1826 // if not a pointer to a function
1827 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1828 if (implicit) { // if not to generic, they have to match
1829 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1830 werror(E_INCOMPAT_PTYPES);
1837 } else { // to a non pointer
1838 if (IS_PTR(optype)) { // from a pointer
1839 if (implicit) { // sneaky
1840 if (IS_INTEGRAL(type)) {
1841 werror(W_PTR2INTEGRAL_NOCAST);
1843 } else { // shouldn't do that with float, array or structure
1844 werror(E_INCOMPAT_TYPES);
1851 printFromToType (optype, type);
1854 /* if they are the same size create an assignment */
1855 if (getSize (type) == getSize (optype) &&
1856 !IS_BITFIELD (type) &&
1858 !IS_FLOAT (optype) &&
1859 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1860 (!IS_SPEC (type) && !IS_SPEC (optype))))
1863 ic = newiCode ('=', NULL, op);
1864 IC_RESULT (ic) = newiTempOperand (type, 0);
1865 SPIL_LOC (IC_RESULT (ic)) =
1866 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1867 IC_RESULT (ic)->isaddr = 0;
1871 ic = newiCode (CAST, operandFromLink (type),
1872 geniCodeRValue (op, FALSE));
1874 IC_RESULT (ic) = newiTempOperand (type, 0);
1877 /* preserve the storage class & output class */
1878 /* of the original variable */
1879 restype = getSpec (operandType (IC_RESULT (ic)));
1880 if (!IS_LITERAL(opetype))
1881 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1882 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1885 return IC_RESULT (ic);
1888 /*-----------------------------------------------------------------*/
1889 /* geniCodeLabel - will create a Label */
1890 /*-----------------------------------------------------------------*/
1892 geniCodeLabel (symbol * label)
1896 ic = newiCodeLabelGoto (LABEL, label);
1900 /*-----------------------------------------------------------------*/
1901 /* geniCodeGoto - will create a Goto */
1902 /*-----------------------------------------------------------------*/
1904 geniCodeGoto (symbol * label)
1908 ic = newiCodeLabelGoto (GOTO, label);
1912 /*-----------------------------------------------------------------*/
1913 /* geniCodeMultiply - gen intermediate code for multiplication */
1914 /*-----------------------------------------------------------------*/
1916 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1923 /* if they are both literal then we know the result */
1924 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1925 return operandFromValue (valMult (left->operand.valOperand,
1926 right->operand.valOperand));
1928 if (IS_LITERAL(retype)) {
1929 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1932 resType = usualBinaryConversions (&left, &right);
1934 rtype = operandType (right);
1935 retype = getSpec (rtype);
1936 ltype = operandType (left);
1937 letype = getSpec (ltype);
1941 SPEC_NOUN(getSpec(resType))=V_INT;
1944 /* if the right is a literal & power of 2 */
1945 /* then make it a left shift */
1946 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1947 efficient in most cases than 2 bytes result = 2 bytes << literal
1948 if port has 1 byte muldiv */
1949 if (p2 && !IS_FLOAT (letype) &&
1950 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1951 (port->support.muldiv == 1)))
1953 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1955 /* LEFT_OP need same size for left and result, */
1956 left = geniCodeCast (resType, left, TRUE);
1957 ltype = operandType (left);
1959 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1963 ic = newiCode ('*', left, right); /* normal multiplication */
1964 /* if the size left or right > 1 then support routine */
1965 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1969 IC_RESULT (ic) = newiTempOperand (resType, 1);
1972 return IC_RESULT (ic);
1975 /*-----------------------------------------------------------------*/
1976 /* geniCodeDivision - gen intermediate code for division */
1977 /*-----------------------------------------------------------------*/
1979 geniCodeDivision (operand * left, operand * right)
1984 sym_link *rtype = operandType (right);
1985 sym_link *retype = getSpec (rtype);
1986 sym_link *ltype = operandType (left);
1987 sym_link *letype = getSpec (ltype);
1989 resType = usualBinaryConversions (&left, &right);
1991 /* if the right is a literal & power of 2
1992 and left is unsigned then make it a
1994 if (IS_LITERAL (retype) &&
1995 !IS_FLOAT (letype) &&
1996 SPEC_USIGN(letype) &&
1997 (p2 = powof2 ((unsigned long)
1998 floatFromVal (right->operand.valOperand)))) {
1999 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2003 ic = newiCode ('/', left, right); /* normal division */
2004 /* if the size left or right > 1 then support routine */
2005 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2008 IC_RESULT (ic) = newiTempOperand (resType, 0);
2011 return IC_RESULT (ic);
2013 /*-----------------------------------------------------------------*/
2014 /* geniCodeModulus - gen intermediate code for modulus */
2015 /*-----------------------------------------------------------------*/
2017 geniCodeModulus (operand * left, operand * right)
2023 /* if they are both literal then we know the result */
2024 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2025 return operandFromValue (valMod (left->operand.valOperand,
2026 right->operand.valOperand));
2028 resType = usualBinaryConversions (&left, &right);
2030 /* now they are the same size */
2031 ic = newiCode ('%', left, right);
2033 /* if the size left or right > 1 then support routine */
2034 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2036 IC_RESULT (ic) = newiTempOperand (resType, 0);
2039 return IC_RESULT (ic);
2042 /*-----------------------------------------------------------------*/
2043 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2044 /*-----------------------------------------------------------------*/
2046 geniCodePtrPtrSubtract (operand * left, operand * right)
2052 /* if they are both literals then */
2053 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2055 result = operandFromValue (valMinus (left->operand.valOperand,
2056 right->operand.valOperand));
2060 ic = newiCode ('-', left, right);
2062 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2066 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2070 // should we really do this? is this ANSI?
2071 return geniCodeDivision (result,
2072 operandFromLit (getSize (ltype->next)));
2075 /*-----------------------------------------------------------------*/
2076 /* geniCodeSubtract - generates code for subtraction */
2077 /*-----------------------------------------------------------------*/
2079 geniCodeSubtract (operand * left, operand * right)
2086 /* if they both pointers then */
2087 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2088 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2089 return geniCodePtrPtrSubtract (left, right);
2091 /* if they are both literal then we know the result */
2092 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2093 && left->isLiteral && right->isLiteral)
2094 return operandFromValue (valMinus (left->operand.valOperand,
2095 right->operand.valOperand));
2097 /* if left is an array or pointer */
2098 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2100 isarray = left->isaddr;
2101 right = geniCodeMultiply (right,
2102 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2103 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2106 { /* make them the same size */
2107 resType = usualBinaryConversions (&left, &right);
2110 ic = newiCode ('-', left, right);
2112 IC_RESULT (ic) = newiTempOperand (resType, 1);
2113 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2115 /* if left or right is a float */
2116 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2120 return IC_RESULT (ic);
2123 /*-----------------------------------------------------------------*/
2124 /* geniCodeAdd - generates iCode for addition */
2125 /*-----------------------------------------------------------------*/
2127 geniCodeAdd (operand * left, operand * right, int lvl)
2135 /* if the right side is LITERAL zero */
2136 /* return the left side */
2137 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2140 /* if left is literal zero return right */
2141 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2144 /* if left is a pointer then size */
2145 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2147 isarray = left->isaddr;
2148 // there is no need to multiply with 1
2149 if (getSize(ltype->next)!=1) {
2150 size = operandFromLit (getSize (ltype->next));
2151 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2153 resType = copyLinkChain (ltype);
2156 { // make them the same size
2157 resType = usualBinaryConversions (&left, &right);
2160 /* if they are both literals then we know */
2161 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2162 && left->isLiteral && right->isLiteral)
2163 return operandFromValue (valPlus (valFromType (letype),
2164 valFromType (retype)));
2166 ic = newiCode ('+', left, right);
2168 IC_RESULT (ic) = newiTempOperand (resType, 1);
2169 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2171 /* if left or right is a float then support
2173 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2178 return IC_RESULT (ic);
2182 /*-----------------------------------------------------------------*/
2183 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2184 /*-----------------------------------------------------------------*/
2186 aggrToPtr (sym_link * type, bool force)
2191 if (IS_PTR (type) && !force)
2194 etype = getSpec (type);
2195 ptype = newLink (DECLARATOR);
2199 /* set the pointer depending on the storage class */
2200 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2204 /*-----------------------------------------------------------------*/
2205 /* geniCodeArray2Ptr - array to pointer */
2206 /*-----------------------------------------------------------------*/
2208 geniCodeArray2Ptr (operand * op)
2210 sym_link *optype = operandType (op);
2211 sym_link *opetype = getSpec (optype);
2213 /* set the pointer depending on the storage class */
2214 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2221 /*-----------------------------------------------------------------*/
2222 /* geniCodeArray - array access */
2223 /*-----------------------------------------------------------------*/
2225 geniCodeArray (operand * left, operand * right,int lvl)
2228 sym_link *ltype = operandType (left);
2232 if (IS_PTR (ltype->next) && left->isaddr)
2234 left = geniCodeRValue (left, FALSE);
2236 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2239 right = geniCodeMultiply (right,
2240 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2242 /* we can check for limits here */
2243 if (isOperandLiteral (right) &&
2246 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2248 werror (E_ARRAY_BOUND);
2249 right = operandFromLit (0);
2252 ic = newiCode ('+', left, right);
2254 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2255 !IS_AGGREGATE (ltype->next) &&
2256 !IS_PTR (ltype->next))
2257 ? ltype : ltype->next), 0);
2259 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2261 return IC_RESULT (ic);
2264 /*-----------------------------------------------------------------*/
2265 /* geniCodeStruct - generates intermediate code for structres */
2266 /*-----------------------------------------------------------------*/
2268 geniCodeStruct (operand * left, operand * right, bool islval)
2271 sym_link *type = operandType (left);
2272 sym_link *etype = getSpec (type);
2274 symbol *element = getStructElement (SPEC_STRUCT (etype),
2275 right->operand.symOperand);
2277 wassert(IS_SYMOP(right));
2279 /* add the offset */
2280 ic = newiCode ('+', left, operandFromLit (element->offset));
2282 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2284 /* preserve the storage & output class of the struct */
2285 /* as well as the volatile attribute */
2286 retype = getSpec (operandType (IC_RESULT (ic)));
2287 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2288 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2289 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2290 SPEC_CONST (retype) |= SPEC_CONST (etype);
2292 if (IS_PTR (element->type))
2293 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2295 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2298 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2301 /*-----------------------------------------------------------------*/
2302 /* geniCodePostInc - generate int code for Post increment */
2303 /*-----------------------------------------------------------------*/
2305 geniCodePostInc (operand * op)
2309 sym_link *optype = operandType (op);
2311 operand *rv = (IS_ITEMP (op) ?
2312 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2314 sym_link *rvtype = operandType (rv);
2317 /* if this is not an address we have trouble */
2320 werror (E_LVALUE_REQUIRED, "++");
2324 rOp = newiTempOperand (rvtype, 0);
2325 OP_SYMBOL(rOp)->noSpilLoc = 1;
2328 OP_SYMBOL(rv)->noSpilLoc = 1;
2330 geniCodeAssign (rOp, rv, 0);
2332 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2333 if (IS_FLOAT (rvtype))
2334 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2336 ic = newiCode ('+', rv, operandFromLit (size));
2338 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2341 geniCodeAssign (op, result, 0);
2347 /*-----------------------------------------------------------------*/
2348 /* geniCodePreInc - generate code for preIncrement */
2349 /*-----------------------------------------------------------------*/
2351 geniCodePreInc (operand * op)
2354 sym_link *optype = operandType (op);
2355 operand *rop = (IS_ITEMP (op) ?
2356 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2358 sym_link *roptype = operandType (rop);
2364 werror (E_LVALUE_REQUIRED, "++");
2369 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2370 if (IS_FLOAT (roptype))
2371 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2373 ic = newiCode ('+', rop, operandFromLit (size));
2374 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2378 return geniCodeAssign (op, result, 0);
2381 /*-----------------------------------------------------------------*/
2382 /* geniCodePostDec - generates code for Post decrement */
2383 /*-----------------------------------------------------------------*/
2385 geniCodePostDec (operand * op)
2389 sym_link *optype = operandType (op);
2391 operand *rv = (IS_ITEMP (op) ?
2392 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2394 sym_link *rvtype = operandType (rv);
2397 /* if this is not an address we have trouble */
2400 werror (E_LVALUE_REQUIRED, "--");
2404 rOp = newiTempOperand (rvtype, 0);
2405 OP_SYMBOL(rOp)->noSpilLoc = 1;
2408 OP_SYMBOL(rv)->noSpilLoc = 1;
2410 geniCodeAssign (rOp, rv, 0);
2412 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2413 if (IS_FLOAT (rvtype))
2414 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2416 ic = newiCode ('-', rv, operandFromLit (size));
2418 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2421 geniCodeAssign (op, result, 0);
2427 /*-----------------------------------------------------------------*/
2428 /* geniCodePreDec - generate code for pre decrement */
2429 /*-----------------------------------------------------------------*/
2431 geniCodePreDec (operand * op)
2434 sym_link *optype = operandType (op);
2435 operand *rop = (IS_ITEMP (op) ?
2436 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2438 sym_link *roptype = operandType (rop);
2444 werror (E_LVALUE_REQUIRED, "--");
2449 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2450 if (IS_FLOAT (roptype))
2451 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2453 ic = newiCode ('-', rop, operandFromLit (size));
2454 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2458 return geniCodeAssign (op, result, 0);
2462 /*-----------------------------------------------------------------*/
2463 /* geniCodeBitwise - gen int code for bitWise operators */
2464 /*-----------------------------------------------------------------*/
2466 geniCodeBitwise (operand * left, operand * right,
2467 int oper, sym_link * resType)
2471 left = geniCodeCast (resType, left, TRUE);
2472 right = geniCodeCast (resType, right, TRUE);
2474 ic = newiCode (oper, left, right);
2475 IC_RESULT (ic) = newiTempOperand (resType, 0);
2478 return IC_RESULT (ic);
2481 /*-----------------------------------------------------------------*/
2482 /* geniCodeAddressOf - gens icode for '&' address of operator */
2483 /*-----------------------------------------------------------------*/
2485 geniCodeAddressOf (operand * op)
2489 sym_link *optype = operandType (op);
2490 sym_link *opetype = getSpec (optype);
2492 /* lvalue check already done in decorateType */
2493 /* this must be a lvalue */
2494 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2495 /* werror (E_LVALUE_REQUIRED,"&"); */
2499 p = newLink (DECLARATOR);
2501 /* set the pointer depending on the storage class */
2502 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2504 p->next = copyLinkChain (optype);
2506 /* if already a temp */
2509 setOperandType (op, p);
2514 /* other wise make this of the type coming in */
2515 ic = newiCode (ADDRESS_OF, op, NULL);
2516 IC_RESULT (ic) = newiTempOperand (p, 1);
2517 IC_RESULT (ic)->isaddr = 0;
2519 return IC_RESULT (ic);
2521 /*-----------------------------------------------------------------*/
2522 /* setOClass - sets the output class depending on the pointer type */
2523 /*-----------------------------------------------------------------*/
2525 setOClass (sym_link * ptr, sym_link * spec)
2527 switch (DCL_TYPE (ptr))
2530 SPEC_OCLS (spec) = data;
2534 SPEC_OCLS (spec) = generic;
2538 SPEC_OCLS (spec) = xdata;
2542 SPEC_OCLS (spec) = code;
2546 SPEC_OCLS (spec) = idata;
2550 SPEC_OCLS (spec) = xstack;
2554 SPEC_OCLS (spec) = eeprom;
2563 /*-----------------------------------------------------------------*/
2564 /* geniCodeDerefPtr - dereference pointer with '*' */
2565 /*-----------------------------------------------------------------*/
2567 geniCodeDerefPtr (operand * op,int lvl)
2569 sym_link *rtype, *retype;
2570 sym_link *optype = operandType (op);
2572 // if this is an array then array access
2573 if (IS_ARRAY (optype)) {
2574 // don't worry, this will be optimized out later
2575 return geniCodeArray (op, operandFromLit (0), lvl);
2578 // just in case someone screws up
2579 wassert (IS_PTR (optype));
2581 if (IS_TRUE_SYMOP (op))
2584 op = geniCodeRValue (op, TRUE);
2587 /* now get rid of the pointer part */
2588 if (isLvaluereq(lvl) && IS_ITEMP (op))
2590 retype = getSpec (rtype = copyLinkChain (optype));
2594 retype = getSpec (rtype = copyLinkChain (optype->next));
2595 /* outputclass needs 2b updated */
2596 setOClass (optype, retype);
2599 op->isGptr = IS_GENPTR (optype);
2601 op->isaddr = (IS_PTR (rtype) ||
2602 IS_STRUCT (rtype) ||
2607 if (!isLvaluereq(lvl))
2608 op = geniCodeRValue (op, TRUE);
2610 setOperandType (op, rtype);
2615 /*-----------------------------------------------------------------*/
2616 /* geniCodeUnaryMinus - does a unary minus of the operand */
2617 /*-----------------------------------------------------------------*/
2619 geniCodeUnaryMinus (operand * op)
2622 sym_link *optype = operandType (op);
2624 if (IS_LITERAL (optype))
2625 return operandFromLit (-floatFromVal (op->operand.valOperand));
2627 ic = newiCode (UNARYMINUS, op, NULL);
2628 IC_RESULT (ic) = newiTempOperand (optype, 0);
2630 return IC_RESULT (ic);
2633 /*-----------------------------------------------------------------*/
2634 /* geniCodeLeftShift - gen i code for left shift */
2635 /*-----------------------------------------------------------------*/
2637 geniCodeLeftShift (operand * left, operand * right)
2641 ic = newiCode (LEFT_OP, left, right);
2642 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2644 return IC_RESULT (ic);
2647 /*-----------------------------------------------------------------*/
2648 /* geniCodeRightShift - gen i code for right shift */
2649 /*-----------------------------------------------------------------*/
2651 geniCodeRightShift (operand * left, operand * right)
2655 ic = newiCode (RIGHT_OP, left, right);
2656 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2658 return IC_RESULT (ic);
2661 /*-----------------------------------------------------------------*/
2662 /* geniCodeLogic- logic code */
2663 /*-----------------------------------------------------------------*/
2665 geniCodeLogic (operand * left, operand * right, int op)
2669 sym_link *rtype = operandType (right);
2670 sym_link *ltype = operandType (left);
2672 /* left is integral type and right is literal then
2673 check if the literal value is within bounds */
2674 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2676 checkConstantRange(ltype,
2677 OP_VALUE(right), "compare operation", 1);
2680 /* if one operand is a pointer and the other is a literal generic void pointer,
2681 change the type of the literal generic void pointer to match the other pointer */
2682 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2683 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2685 /* find left's definition */
2686 ic = (iCode *) setFirstItem (iCodeChain);
2689 if (((ic->op == CAST) || (ic->op == '='))
2690 && isOperandEqual(left, IC_RESULT (ic)))
2693 ic = setNextItem (iCodeChain);
2695 /* if casting literal to generic pointer, then cast to rtype instead */
2696 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2698 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2699 ltype = operandType(left);
2702 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2703 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2705 /* find right's definition */
2706 ic = (iCode *) setFirstItem (iCodeChain);
2709 if (((ic->op == CAST) || (ic->op == '='))
2710 && isOperandEqual(right, IC_RESULT (ic)))
2713 ic = setNextItem (iCodeChain);
2715 /* if casting literal to generic pointer, then cast to rtype instead */
2716 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2718 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2719 rtype = operandType(right);
2723 ctype = usualBinaryConversions (&left, &right);
2725 ic = newiCode (op, left, right);
2726 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2728 /* if comparing float
2729 and not a '==' || '!=' || '&&' || '||' (these
2731 if (IS_FLOAT(ctype) &&
2739 return IC_RESULT (ic);
2742 /*-----------------------------------------------------------------*/
2743 /* geniCodeUnary - for a a generic unary operation */
2744 /*-----------------------------------------------------------------*/
2746 geniCodeUnary (operand * op, int oper)
2748 iCode *ic = newiCode (oper, op, NULL);
2750 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2752 return IC_RESULT (ic);
2755 /*-----------------------------------------------------------------*/
2756 /* geniCodeConditional - geniCode for '?' ':' operation */
2757 /*-----------------------------------------------------------------*/
2759 geniCodeConditional (ast * tree,int lvl)
2762 symbol *falseLabel = newiTempLabel (NULL);
2763 symbol *exitLabel = newiTempLabel (NULL);
2764 operand *cond = ast2iCode (tree->left,lvl+1);
2765 operand *true, *false, *result;
2767 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2771 true = ast2iCode (tree->right->left,lvl+1);
2773 /* move the value to a new Operand */
2774 result = newiTempOperand (tree->right->ftype, 0);
2775 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2777 /* generate an unconditional goto */
2778 geniCodeGoto (exitLabel);
2780 /* now for the right side */
2781 geniCodeLabel (falseLabel);
2783 false = ast2iCode (tree->right->right,lvl+1);
2784 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2786 /* create the exit label */
2787 geniCodeLabel (exitLabel);
2792 /*-----------------------------------------------------------------*/
2793 /* geniCodeAssign - generate code for assignment */
2794 /*-----------------------------------------------------------------*/
2796 geniCodeAssign (operand * left, operand * right, int nosupdate)
2799 sym_link *ltype = operandType (left);
2800 sym_link *rtype = operandType (right);
2802 if (!left->isaddr && !IS_ITEMP (left))
2804 werror (E_LVALUE_REQUIRED, "assignment");
2808 /* left is integral type and right is literal then
2809 check if the literal value is within bounds */
2810 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2812 checkConstantRange(ltype,
2813 OP_VALUE(right), "= operation", 0);
2816 /* if the left & right type don't exactly match */
2817 /* if pointer set then make sure the check is
2818 done with the type & not the pointer */
2819 /* then cast rights type to left */
2821 /* first check the type for pointer assignement */
2822 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2823 compareType (ltype, rtype) <= 0)
2825 if (compareType (ltype->next, rtype) < 0)
2826 right = geniCodeCast (ltype->next, right, TRUE);
2828 else if (compareType (ltype, rtype) < 0)
2829 right = geniCodeCast (ltype, right, TRUE);
2831 /* if left is a true symbol & ! volatile
2832 create an assignment to temporary for
2833 the right & then assign this temporary
2834 to the symbol this is SSA . isn't it simple
2835 and folks have published mountains of paper on it */
2836 if (IS_TRUE_SYMOP (left) &&
2837 !isOperandVolatile (left, FALSE) &&
2838 isOperandGlobal (left))
2842 if (IS_TRUE_SYMOP (right))
2843 sym = OP_SYMBOL (right);
2844 ic = newiCode ('=', NULL, right);
2845 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2846 SPIL_LOC (right) = sym;
2850 ic = newiCode ('=', NULL, right);
2851 IC_RESULT (ic) = left;
2854 /* if left isgptr flag is set then support
2855 routine will be required */
2859 ic->nosupdate = nosupdate;
2863 /*-----------------------------------------------------------------*/
2864 /* geniCodeDummyRead - generate code for dummy read */
2865 /*-----------------------------------------------------------------*/
2867 geniCodeDummyRead (operand * op)
2870 sym_link *type = operandType (op);
2872 if (!IS_VOLATILE(type))
2875 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2881 /*-----------------------------------------------------------------*/
2882 /* geniCodeSEParms - generate code for side effecting fcalls */
2883 /*-----------------------------------------------------------------*/
2885 geniCodeSEParms (ast * parms,int lvl)
2890 if (parms->type == EX_OP && parms->opval.op == PARAM)
2892 geniCodeSEParms (parms->left,lvl);
2893 geniCodeSEParms (parms->right,lvl);
2897 /* hack don't like this but too lazy to think of
2899 if (IS_ADDRESS_OF_OP (parms))
2900 parms->left->lvalue = 1;
2902 if (IS_CAST_OP (parms) &&
2903 IS_PTR (parms->ftype) &&
2904 IS_ADDRESS_OF_OP (parms->right))
2905 parms->right->left->lvalue = 1;
2907 parms->opval.oprnd =
2908 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2910 parms->type = EX_OPERAND;
2911 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2912 SPEC_ARGREG(parms->ftype);
2915 /*-----------------------------------------------------------------*/
2916 /* geniCodeParms - generates parameters */
2917 /*-----------------------------------------------------------------*/
2919 geniCodeParms (ast * parms, value *argVals, int *stack,
2920 sym_link * fetype, symbol * func,int lvl)
2928 if (argVals==NULL) {
2930 argVals=FUNC_ARGS(func->type);
2933 /* if this is a param node then do the left & right */
2934 if (parms->type == EX_OP && parms->opval.op == PARAM)
2936 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2937 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2941 /* get the parameter value */
2942 if (parms->type == EX_OPERAND)
2943 pval = parms->opval.oprnd;
2946 /* maybe this else should go away ?? */
2947 /* hack don't like this but too lazy to think of
2949 if (IS_ADDRESS_OF_OP (parms))
2950 parms->left->lvalue = 1;
2952 if (IS_CAST_OP (parms) &&
2953 IS_PTR (parms->ftype) &&
2954 IS_ADDRESS_OF_OP (parms->right))
2955 parms->right->left->lvalue = 1;
2957 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2960 /* if register parm then make it a send */
2961 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2962 IFFUNC_ISBUILTIN(func->type))
2964 ic = newiCode (SEND, pval, NULL);
2965 ic->argreg = SPEC_ARGREG(parms->etype);
2966 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2971 /* now decide whether to push or assign */
2972 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2976 operand *top = operandFromSymbol (argVals->sym);
2977 /* clear useDef and other bitVectors */
2978 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
2979 geniCodeAssign (top, pval, 1);
2983 sym_link *p = operandType (pval);
2985 ic = newiCode (IPUSH, pval, NULL);
2987 /* update the stack adjustment */
2988 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2993 argVals=argVals->next;
2997 /*-----------------------------------------------------------------*/
2998 /* geniCodeCall - generates temp code for calling */
2999 /*-----------------------------------------------------------------*/
3001 geniCodeCall (operand * left, ast * parms,int lvl)
3005 sym_link *type, *etype;
3008 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3009 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3010 werror (E_FUNCTION_EXPECTED);
3014 /* take care of parameters with side-effecting
3015 function calls in them, this is required to take care
3016 of overlaying function parameters */
3017 geniCodeSEParms (parms,lvl);
3019 /* first the parameters */
3020 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3022 /* now call : if symbol then pcall */
3023 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3024 ic = newiCode (PCALL, left, NULL);
3026 ic = newiCode (CALL, left, NULL);
3029 type = copyLinkChain (operandType (left)->next);
3030 etype = getSpec (type);
3031 SPEC_EXTR (etype) = 0;
3032 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3036 /* stack adjustment after call */
3037 ic->parmBytes = stack;
3042 /*-----------------------------------------------------------------*/
3043 /* geniCodeReceive - generate intermediate code for "receive" */
3044 /*-----------------------------------------------------------------*/
3046 geniCodeReceive (value * args)
3048 /* for all arguments that are passed in registers */
3052 if (IS_REGPARM (args->etype))
3054 operand *opr = operandFromValue (args);
3056 symbol *sym = OP_SYMBOL (opr);
3059 /* we will use it after all optimizations
3060 and before liveRange calculation */
3061 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3064 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
3065 options.stackAuto == 0 &&
3066 (!(options.model == MODEL_FLAT24)) )
3071 opl = newiTempOperand (args->type, 0);
3073 sym->reqv->key = sym->key;
3074 OP_SYMBOL (sym->reqv)->key = sym->key;
3075 OP_SYMBOL (sym->reqv)->isreqv = 1;
3076 OP_SYMBOL (sym->reqv)->islocal = 0;
3077 SPIL_LOC (sym->reqv) = sym;
3081 ic = newiCode (RECEIVE, NULL, NULL);
3082 ic->argreg = SPEC_ARGREG(args->etype);
3084 currFunc->recvSize = getSize (sym->type);
3087 IC_RESULT (ic) = opr;
3095 /*-----------------------------------------------------------------*/
3096 /* geniCodeFunctionBody - create the function body */
3097 /*-----------------------------------------------------------------*/
3099 geniCodeFunctionBody (ast * tree,int lvl)
3106 /* reset the auto generation */
3112 func = ast2iCode (tree->left,lvl+1);
3113 fetype = getSpec (operandType (func));
3115 savelineno = lineno;
3116 lineno = OP_SYMBOL (func)->lineDef;
3117 /* create an entry label */
3118 geniCodeLabel (entryLabel);
3119 lineno = savelineno;
3121 /* create a proc icode */
3122 ic = newiCode (FUNCTION, func, NULL);
3123 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3127 /* for all parameters that are passed
3128 on registers add a "receive" */
3129 geniCodeReceive (tree->values.args);
3131 /* generate code for the body */
3132 ast2iCode (tree->right,lvl+1);
3134 /* create a label for return */
3135 geniCodeLabel (returnLabel);
3137 /* now generate the end proc */
3138 ic = newiCode (ENDFUNCTION, func, NULL);
3143 /*-----------------------------------------------------------------*/
3144 /* geniCodeReturn - gen icode for 'return' statement */
3145 /*-----------------------------------------------------------------*/
3147 geniCodeReturn (operand * op)
3151 /* if the operand is present force an rvalue */
3153 op = geniCodeRValue (op, FALSE);
3155 ic = newiCode (RETURN, op, NULL);
3159 /*-----------------------------------------------------------------*/
3160 /* geniCodeIfx - generates code for extended if statement */
3161 /*-----------------------------------------------------------------*/
3163 geniCodeIfx (ast * tree,int lvl)
3166 operand *condition = ast2iCode (tree->left,lvl+1);
3169 /* if condition is null then exit */
3173 condition = geniCodeRValue (condition, FALSE);
3175 cetype = getSpec (operandType (condition));
3176 /* if the condition is a literal */
3177 if (IS_LITERAL (cetype))
3179 if (floatFromVal (condition->operand.valOperand))
3181 if (tree->trueLabel)
3182 geniCodeGoto (tree->trueLabel);
3188 if (tree->falseLabel)
3189 geniCodeGoto (tree->falseLabel);
3196 if (tree->trueLabel)
3198 ic = newiCodeCondition (condition,
3203 if (tree->falseLabel)
3204 geniCodeGoto (tree->falseLabel);
3208 ic = newiCodeCondition (condition,
3215 ast2iCode (tree->right,lvl+1);
3218 /*-----------------------------------------------------------------*/
3219 /* geniCodeJumpTable - tries to create a jump table for switch */
3220 /*-----------------------------------------------------------------*/
3222 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3224 int min = 0, max = 0, t, cnt = 0;
3230 int needRangeCheck = !optimize.noJTabBoundary
3231 || tree->values.switchVals.swDefault;
3233 if (!tree || !caseVals)
3236 /* the criteria for creating a jump table is */
3237 /* all integer numbers between the maximum & minimum must */
3238 /* be present , the maximum value should not exceed 255 */
3239 min = max = (int) floatFromVal (vch = caseVals);
3240 SNPRINTF (buffer, sizeof(buffer),
3242 tree->values.switchVals.swNum,
3244 addSet (&labels, newiTempLabel (buffer));
3246 /* if there is only one case value then no need */
3247 if (!(vch = vch->next))
3252 if (((t = (int) floatFromVal (vch)) - max) != 1)
3254 SNPRINTF (buffer, sizeof(buffer),
3256 tree->values.switchVals.swNum,
3258 addSet (&labels, newiTempLabel (buffer));
3264 /* if the number of case statements <= 2 then */
3265 /* it is not economical to create the jump table */
3266 /* since two compares are needed for boundary conditions */
3267 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3270 if (tree->values.switchVals.swDefault)
3272 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3276 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3280 falseLabel = newiTempLabel (buffer);
3282 /* so we can create a jumptable */
3283 /* first we rule out the boundary conditions */
3284 /* if only optimization says so */
3287 sym_link *cetype = getSpec (operandType (cond));
3288 /* no need to check the lower bound if
3289 the condition is unsigned & minimum value is zero */
3290 if (!(min == 0 && SPEC_USIGN (cetype)))
3292 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3293 ic = newiCodeCondition (boundary, falseLabel, NULL);
3297 /* now for upper bounds */
3298 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3299 ic = newiCodeCondition (boundary, falseLabel, NULL);
3303 /* if the min is not zero then we no make it zero */
3306 cond = geniCodeSubtract (cond, operandFromLit (min));
3307 if (!IS_LITERAL(getSpec(operandType(cond))))
3308 setOperandType (cond, UCHARTYPE);
3311 /* now create the jumptable */
3312 ic = newiCode (JUMPTABLE, NULL, NULL);
3313 IC_JTCOND (ic) = cond;
3314 IC_JTLABELS (ic) = labels;
3319 /*-----------------------------------------------------------------*/
3320 /* geniCodeSwitch - changes a switch to a if statement */
3321 /*-----------------------------------------------------------------*/
3323 geniCodeSwitch (ast * tree,int lvl)
3326 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3327 value *caseVals = tree->values.switchVals.swVals;
3328 symbol *trueLabel, *falseLabel;
3330 /* If the condition is a literal, then just jump to the */
3331 /* appropriate case label. */
3332 if (IS_LITERAL(getSpec(operandType(cond))))
3334 int switchVal, caseVal;
3336 switchVal = (int) floatFromVal (cond->operand.valOperand);
3339 caseVal = (int) floatFromVal (caseVals);
3340 if (caseVal == switchVal)
3342 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3343 tree->values.switchVals.swNum, caseVal);
3344 trueLabel = newiTempLabel (buffer);
3345 geniCodeGoto (trueLabel);
3348 caseVals = caseVals->next;
3350 goto defaultOrBreak;
3353 /* if we can make this a jump table */
3354 if (geniCodeJumpTable (cond, caseVals, tree))
3355 goto jumpTable; /* no need for the comparison */
3357 /* for the cases defined do */
3361 operand *compare = geniCodeLogic (cond,
3362 operandFromValue (caseVals),
3365 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3366 tree->values.switchVals.swNum,
3367 (int) floatFromVal (caseVals));
3368 trueLabel = newiTempLabel (buffer);
3370 ic = newiCodeCondition (compare, trueLabel, NULL);
3372 caseVals = caseVals->next;
3377 /* if default is present then goto break else break */
3378 if (tree->values.switchVals.swDefault)
3380 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3384 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3387 falseLabel = newiTempLabel (buffer);
3388 geniCodeGoto (falseLabel);
3391 ast2iCode (tree->right,lvl+1);
3394 /*-----------------------------------------------------------------*/
3395 /* geniCodeInline - intermediate code for inline assembler */
3396 /*-----------------------------------------------------------------*/
3398 geniCodeInline (ast * tree)
3402 ic = newiCode (INLINEASM, NULL, NULL);
3403 IC_INLINE (ic) = tree->values.inlineasm;
3407 /*-----------------------------------------------------------------*/
3408 /* geniCodeArrayInit - intermediate code for array initializer */
3409 /*-----------------------------------------------------------------*/
3411 geniCodeArrayInit (ast * tree, operand *array)
3415 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3416 ic = newiCode (ARRAYINIT, array, NULL);
3417 IC_ARRAYILIST (ic) = tree->values.constlist;
3419 operand *left=newOperand(), *right=newOperand();
3420 left->type=right->type=SYMBOL;
3421 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3422 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3423 ic = newiCode (ARRAYINIT, left, right);
3428 /*-----------------------------------------------------------------*/
3429 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3430 /* particular case. Ie : assigning or dereferencing array or ptr */
3431 /*-----------------------------------------------------------------*/
3432 set * lvaluereqSet = NULL;
3433 typedef struct lvalItem
3440 /*-----------------------------------------------------------------*/
3441 /* addLvaluereq - add a flag for lvalreq for current ast level */
3442 /*-----------------------------------------------------------------*/
3443 void addLvaluereq(int lvl)
3445 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3448 addSetHead(&lvaluereqSet,lpItem);
3451 /*-----------------------------------------------------------------*/
3452 /* delLvaluereq - del a flag for lvalreq for current ast level */
3453 /*-----------------------------------------------------------------*/
3457 lpItem = getSet(&lvaluereqSet);
3458 if(lpItem) Safe_free(lpItem);
3460 /*-----------------------------------------------------------------*/
3461 /* clearLvaluereq - clear lvalreq flag */
3462 /*-----------------------------------------------------------------*/
3463 void clearLvaluereq()
3466 lpItem = peekSet(lvaluereqSet);
3467 if(lpItem) lpItem->req = 0;
3469 /*-----------------------------------------------------------------*/
3470 /* getLvaluereq - get the last lvalreq level */
3471 /*-----------------------------------------------------------------*/
3472 int getLvaluereqLvl()
3475 lpItem = peekSet(lvaluereqSet);
3476 if(lpItem) return lpItem->lvl;
3479 /*-----------------------------------------------------------------*/
3480 /* isLvaluereq - is lvalreq valid for this level ? */
3481 /*-----------------------------------------------------------------*/
3482 int isLvaluereq(int lvl)
3485 lpItem = peekSet(lvaluereqSet);
3486 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3490 /*-----------------------------------------------------------------*/
3491 /* ast2iCode - creates an icodeList from an ast */
3492 /*-----------------------------------------------------------------*/
3494 ast2iCode (ast * tree,int lvl)
3496 operand *left = NULL;
3497 operand *right = NULL;
3501 /* set the global variables for filename & line number */
3503 filename = tree->filename;
3505 lineno = tree->lineno;
3507 block = tree->block;
3509 scopeLevel = tree->level;
3511 if (tree->type == EX_VALUE)
3512 return operandFromValue (tree->opval.val);
3514 if (tree->type == EX_LINK)
3515 return operandFromLink (tree->opval.lnk);
3517 /* if we find a nullop */
3518 if (tree->type == EX_OP &&
3519 (tree->opval.op == NULLOP ||
3520 tree->opval.op == BLOCK))
3522 if (tree->left && tree->left->type == EX_VALUE)
3523 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3525 ast2iCode (tree->left,lvl+1);
3526 if (tree->right && tree->right->type == EX_VALUE)
3527 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3529 ast2iCode (tree->right,lvl+1);
3533 /* special cases for not evaluating */
3534 if (tree->opval.op != ':' &&
3535 tree->opval.op != '?' &&
3536 tree->opval.op != CALL &&
3537 tree->opval.op != IFX &&
3538 tree->opval.op != LABEL &&
3539 tree->opval.op != GOTO &&
3540 tree->opval.op != SWITCH &&
3541 tree->opval.op != FUNCTION &&
3542 tree->opval.op != INLINEASM)
3545 if (IS_ASSIGN_OP (tree->opval.op) ||
3546 IS_DEREF_OP (tree) ||
3547 (tree->opval.op == '&' && !tree->right) ||
3548 tree->opval.op == PTR_OP)
3551 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3552 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3555 left = operandFromAst (tree->left,lvl);
3557 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3558 left = geniCodeRValue (left, TRUE);
3562 left = operandFromAst (tree->left,lvl);
3564 if (tree->opval.op == INC_OP ||
3565 tree->opval.op == DEC_OP)
3568 right = operandFromAst (tree->right,lvl);
3573 right = operandFromAst (tree->right,lvl);
3577 /* now depending on the type of operand */
3578 /* this will be a biggy */
3579 switch (tree->opval.op)
3582 case '[': /* array operation */
3584 //sym_link *ltype = operandType (left);
3585 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3586 left = geniCodeRValue (left, FALSE);
3587 right = geniCodeRValue (right, TRUE);
3590 return geniCodeArray (left, right,lvl);
3592 case '.': /* structure dereference */
3593 if (IS_PTR (operandType (left)))
3594 left = geniCodeRValue (left, TRUE);
3596 left = geniCodeRValue (left, FALSE);
3598 return geniCodeStruct (left, right, tree->lvalue);
3600 case PTR_OP: /* structure pointer dereference */
3603 pType = operandType (left);
3604 left = geniCodeRValue (left, TRUE);
3606 setOClass (pType, getSpec (operandType (left)));
3609 return geniCodeStruct (left, right, tree->lvalue);
3611 case INC_OP: /* increment operator */
3613 return geniCodePostInc (left);
3615 return geniCodePreInc (right);
3617 case DEC_OP: /* decrement operator */
3619 return geniCodePostDec (left);
3621 return geniCodePreDec (right);
3623 case '&': /* bitwise and or address of operator */
3625 { /* this is a bitwise operator */
3626 left = geniCodeRValue (left, FALSE);
3627 right = geniCodeRValue (right, FALSE);
3628 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3631 return geniCodeAddressOf (left);
3633 case '|': /* bitwise or & xor */
3635 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3636 geniCodeRValue (right, FALSE),
3641 return geniCodeDivision (geniCodeRValue (left, FALSE),
3642 geniCodeRValue (right, FALSE));
3645 return geniCodeModulus (geniCodeRValue (left, FALSE),
3646 geniCodeRValue (right, FALSE));
3649 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3650 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3652 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3656 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3657 geniCodeRValue (right, FALSE));
3659 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3663 return geniCodeAdd (geniCodeRValue (left, FALSE),
3664 geniCodeRValue (right, FALSE),lvl);
3666 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3669 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3670 geniCodeRValue (right, FALSE));
3673 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3674 geniCodeRValue (right, FALSE));
3676 #if 0 // this indeed needs a second thought
3680 // let's keep this simple: get the rvalue we need
3681 op=geniCodeRValue (right, FALSE);
3682 // now cast it to whatever we want
3683 op=geniCodeCast (operandType(left), op, FALSE);
3684 // if this is going to be used as an lvalue, make it so
3690 #else // bug #604575, is it a bug ????
3691 return geniCodeCast (operandType (left),
3692 geniCodeRValue (right, FALSE), FALSE);
3698 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3703 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3704 setOperandType (op, UCHARTYPE);
3715 /* different compilers (even different gccs) evaluate
3716 the two calls in a different order. to get the same
3717 result on all machines we've to specify a clear sequence.
3718 return geniCodeLogic (geniCodeRValue (left, FALSE),
3719 geniCodeRValue (right, FALSE),
3723 operand *leftOp, *rightOp;
3725 rightOp = geniCodeRValue (right, FALSE);
3726 leftOp = geniCodeRValue (left , FALSE);
3728 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3731 return geniCodeConditional (tree,lvl);
3734 return operandFromLit (getSize (tree->right->ftype));
3738 sym_link *rtype = operandType (right);
3739 sym_link *ltype = operandType (left);
3740 if (IS_PTR (rtype) && IS_ITEMP (right)
3741 && right->isaddr && compareType (rtype->next, ltype) == 1)
3742 right = geniCodeRValue (right, TRUE);
3744 right = geniCodeRValue (right, FALSE);
3746 geniCodeAssign (left, right, 0);
3751 geniCodeAssign (left,
3752 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3754 geniCodeRValue (right, FALSE),FALSE), 0);
3758 geniCodeAssign (left,
3759 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3761 geniCodeRValue (right, FALSE)), 0);
3764 geniCodeAssign (left,
3765 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3767 geniCodeRValue (right, FALSE)), 0);
3770 sym_link *rtype = operandType (right);
3771 sym_link *ltype = operandType (left);
3772 if (IS_PTR (rtype) && IS_ITEMP (right)
3773 && right->isaddr && compareType (rtype->next, ltype) == 1)
3774 right = geniCodeRValue (right, TRUE);
3776 right = geniCodeRValue (right, FALSE);
3779 return geniCodeAssign (left,
3780 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3786 sym_link *rtype = operandType (right);
3787 sym_link *ltype = operandType (left);
3788 if (IS_PTR (rtype) && IS_ITEMP (right)
3789 && right->isaddr && compareType (rtype->next, ltype) == 1)
3791 right = geniCodeRValue (right, TRUE);
3795 right = geniCodeRValue (right, FALSE);
3798 geniCodeAssign (left,
3799 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3805 geniCodeAssign (left,
3806 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3808 geniCodeRValue (right, FALSE)), 0);
3811 geniCodeAssign (left,
3812 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3814 geniCodeRValue (right, FALSE)), 0);
3817 geniCodeAssign (left,
3818 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3820 geniCodeRValue (right, FALSE),
3822 operandType (left)), 0);
3825 geniCodeAssign (left,
3826 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3828 geniCodeRValue (right, FALSE),
3830 operandType (left)), 0);
3833 geniCodeAssign (left,
3834 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3836 geniCodeRValue (right, FALSE),
3838 operandType (left)), 0);
3840 return geniCodeRValue (right, FALSE);
3843 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3846 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3847 return ast2iCode (tree->right,lvl+1);
3850 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3851 return ast2iCode (tree->right,lvl+1);
3854 geniCodeFunctionBody (tree,lvl);
3858 geniCodeReturn (right);
3862 geniCodeIfx (tree,lvl);
3866 geniCodeSwitch (tree,lvl);
3870 geniCodeInline (tree);
3874 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3881 /*-----------------------------------------------------------------*/
3882 /* reverseICChain - gets from the list and creates a linkedlist */
3883 /*-----------------------------------------------------------------*/
3890 while ((loop = getSet (&iCodeChain)))
3902 /*-----------------------------------------------------------------*/
3903 /* iCodeFromAst - given an ast will convert it to iCode */
3904 /*-----------------------------------------------------------------*/
3906 iCodeFromAst (ast * tree)
3908 returnLabel = newiTempLabel ("_return");
3909 entryLabel = newiTempLabel ("_entry");
3911 return reverseiCChain ();
3914 static const char *opTypeToStr(OPTYPE op)
3918 case SYMBOL: return "symbol";
3919 case VALUE: return "value";
3920 case TYPE: return "type";
3922 return "undefined type";
3926 operand *validateOpType(operand *op,
3933 if (op && op->type == type)
3938 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
3939 " expected %s, got %s\n",
3940 macro, args, file, line,
3941 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
3943 return op; // never reached, makes compiler happy.