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));
2262 return IC_RESULT (ic);
2265 /*-----------------------------------------------------------------*/
2266 /* geniCodeStruct - generates intermediate code for structres */
2267 /*-----------------------------------------------------------------*/
2269 geniCodeStruct (operand * left, operand * right, bool islval)
2272 sym_link *type = operandType (left);
2273 sym_link *etype = getSpec (type);
2275 symbol *element = getStructElement (SPEC_STRUCT (etype),
2276 right->operand.symOperand);
2278 wassert(IS_SYMOP(right));
2280 /* add the offset */
2281 ic = newiCode ('+', left, operandFromLit (element->offset));
2283 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2285 /* preserve the storage & output class of the struct */
2286 /* as well as the volatile attribute */
2287 retype = getSpec (operandType (IC_RESULT (ic)));
2288 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2289 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2290 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2291 SPEC_CONST (retype) |= SPEC_CONST (etype);
2293 if (IS_PTR (element->type))
2294 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2296 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2299 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2302 /*-----------------------------------------------------------------*/
2303 /* geniCodePostInc - generate int code for Post increment */
2304 /*-----------------------------------------------------------------*/
2306 geniCodePostInc (operand * op)
2310 sym_link *optype = operandType (op);
2312 operand *rv = (IS_ITEMP (op) ?
2313 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2315 sym_link *rvtype = operandType (rv);
2318 /* if this is not an address we have trouble */
2321 werror (E_LVALUE_REQUIRED, "++");
2325 rOp = newiTempOperand (rvtype, 0);
2326 OP_SYMBOL(rOp)->noSpilLoc = 1;
2329 OP_SYMBOL(rv)->noSpilLoc = 1;
2331 geniCodeAssign (rOp, rv, 0);
2333 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2334 if (IS_FLOAT (rvtype))
2335 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2337 ic = newiCode ('+', rv, operandFromLit (size));
2339 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2342 geniCodeAssign (op, result, 0);
2348 /*-----------------------------------------------------------------*/
2349 /* geniCodePreInc - generate code for preIncrement */
2350 /*-----------------------------------------------------------------*/
2352 geniCodePreInc (operand * op, bool lvalue)
2355 sym_link *optype = operandType (op);
2356 operand *rop = (IS_ITEMP (op) ?
2357 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2359 sym_link *roptype = operandType (rop);
2365 werror (E_LVALUE_REQUIRED, "++");
2370 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2371 if (IS_FLOAT (roptype))
2372 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2374 ic = newiCode ('+', rop, operandFromLit (size));
2375 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2378 (void) geniCodeAssign (op, result, 0);
2385 /*-----------------------------------------------------------------*/
2386 /* geniCodePostDec - generates code for Post decrement */
2387 /*-----------------------------------------------------------------*/
2389 geniCodePostDec (operand * op)
2393 sym_link *optype = operandType (op);
2395 operand *rv = (IS_ITEMP (op) ?
2396 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2398 sym_link *rvtype = operandType (rv);
2401 /* if this is not an address we have trouble */
2404 werror (E_LVALUE_REQUIRED, "--");
2408 rOp = newiTempOperand (rvtype, 0);
2409 OP_SYMBOL(rOp)->noSpilLoc = 1;
2412 OP_SYMBOL(rv)->noSpilLoc = 1;
2414 geniCodeAssign (rOp, rv, 0);
2416 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2417 if (IS_FLOAT (rvtype))
2418 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2420 ic = newiCode ('-', rv, operandFromLit (size));
2422 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2425 geniCodeAssign (op, result, 0);
2431 /*-----------------------------------------------------------------*/
2432 /* geniCodePreDec - generate code for pre decrement */
2433 /*-----------------------------------------------------------------*/
2435 geniCodePreDec (operand * op, bool lvalue)
2438 sym_link *optype = operandType (op);
2439 operand *rop = (IS_ITEMP (op) ?
2440 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2442 sym_link *roptype = operandType (rop);
2448 werror (E_LVALUE_REQUIRED, "--");
2453 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2454 if (IS_FLOAT (roptype))
2455 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2457 ic = newiCode ('-', rop, operandFromLit (size));
2458 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2461 (void) geniCodeAssign (op, result, 0);
2469 /*-----------------------------------------------------------------*/
2470 /* geniCodeBitwise - gen int code for bitWise operators */
2471 /*-----------------------------------------------------------------*/
2473 geniCodeBitwise (operand * left, operand * right,
2474 int oper, sym_link * resType)
2478 left = geniCodeCast (resType, left, TRUE);
2479 right = geniCodeCast (resType, right, TRUE);
2481 ic = newiCode (oper, left, right);
2482 IC_RESULT (ic) = newiTempOperand (resType, 0);
2485 return IC_RESULT (ic);
2488 /*-----------------------------------------------------------------*/
2489 /* geniCodeAddressOf - gens icode for '&' address of operator */
2490 /*-----------------------------------------------------------------*/
2492 geniCodeAddressOf (operand * op)
2496 sym_link *optype = operandType (op);
2497 sym_link *opetype = getSpec (optype);
2499 /* lvalue check already done in decorateType */
2500 /* this must be a lvalue */
2501 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2502 /* werror (E_LVALUE_REQUIRED,"&"); */
2506 p = newLink (DECLARATOR);
2508 /* set the pointer depending on the storage class */
2509 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2511 p->next = copyLinkChain (optype);
2513 /* if already a temp */
2516 setOperandType (op, p);
2521 /* other wise make this of the type coming in */
2522 ic = newiCode (ADDRESS_OF, op, NULL);
2523 IC_RESULT (ic) = newiTempOperand (p, 1);
2524 IC_RESULT (ic)->isaddr = 0;
2526 return IC_RESULT (ic);
2528 /*-----------------------------------------------------------------*/
2529 /* setOClass - sets the output class depending on the pointer type */
2530 /*-----------------------------------------------------------------*/
2532 setOClass (sym_link * ptr, sym_link * spec)
2534 switch (DCL_TYPE (ptr))
2537 SPEC_OCLS (spec) = data;
2541 SPEC_OCLS (spec) = generic;
2545 SPEC_OCLS (spec) = xdata;
2549 SPEC_OCLS (spec) = code;
2553 SPEC_OCLS (spec) = idata;
2557 SPEC_OCLS (spec) = xstack;
2561 SPEC_OCLS (spec) = eeprom;
2570 /*-----------------------------------------------------------------*/
2571 /* geniCodeDerefPtr - dereference pointer with '*' */
2572 /*-----------------------------------------------------------------*/
2574 geniCodeDerefPtr (operand * op,int lvl)
2576 sym_link *rtype, *retype;
2577 sym_link *optype = operandType (op);
2579 // if this is an array then array access
2580 if (IS_ARRAY (optype)) {
2581 // don't worry, this will be optimized out later
2582 return geniCodeArray (op, operandFromLit (0), lvl);
2585 // just in case someone screws up
2586 wassert (IS_PTR (optype));
2588 if (IS_TRUE_SYMOP (op))
2591 op = geniCodeRValue (op, TRUE);
2594 /* now get rid of the pointer part */
2595 if (isLvaluereq(lvl) && IS_ITEMP (op))
2597 retype = getSpec (rtype = copyLinkChain (optype));
2601 retype = getSpec (rtype = copyLinkChain (optype->next));
2602 /* outputclass needs 2b updated */
2603 setOClass (optype, retype);
2606 op->isGptr = IS_GENPTR (optype);
2608 op->isaddr = (IS_PTR (rtype) ||
2609 IS_STRUCT (rtype) ||
2614 if (!isLvaluereq(lvl))
2615 op = geniCodeRValue (op, TRUE);
2617 setOperandType (op, rtype);
2622 /*-----------------------------------------------------------------*/
2623 /* geniCodeUnaryMinus - does a unary minus of the operand */
2624 /*-----------------------------------------------------------------*/
2626 geniCodeUnaryMinus (operand * op)
2629 sym_link *optype = operandType (op);
2631 if (IS_LITERAL (optype))
2632 return operandFromLit (-floatFromVal (op->operand.valOperand));
2634 ic = newiCode (UNARYMINUS, op, NULL);
2635 IC_RESULT (ic) = newiTempOperand (optype, 0);
2637 return IC_RESULT (ic);
2640 /*-----------------------------------------------------------------*/
2641 /* geniCodeLeftShift - gen i code for left shift */
2642 /*-----------------------------------------------------------------*/
2644 geniCodeLeftShift (operand * left, operand * right)
2648 ic = newiCode (LEFT_OP, left, right);
2649 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2651 return IC_RESULT (ic);
2654 /*-----------------------------------------------------------------*/
2655 /* geniCodeRightShift - gen i code for right shift */
2656 /*-----------------------------------------------------------------*/
2658 geniCodeRightShift (operand * left, operand * right)
2662 ic = newiCode (RIGHT_OP, left, right);
2663 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2665 return IC_RESULT (ic);
2668 /*-----------------------------------------------------------------*/
2669 /* geniCodeLogic- logic code */
2670 /*-----------------------------------------------------------------*/
2672 geniCodeLogic (operand * left, operand * right, int op)
2676 sym_link *rtype = operandType (right);
2677 sym_link *ltype = operandType (left);
2679 /* left is integral type and right is literal then
2680 check if the literal value is within bounds */
2681 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2683 checkConstantRange(ltype,
2684 OP_VALUE(right), "compare operation", 1);
2687 /* if one operand is a pointer and the other is a literal generic void pointer,
2688 change the type of the literal generic void pointer to match the other pointer */
2689 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2690 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2692 /* find left's definition */
2693 ic = (iCode *) setFirstItem (iCodeChain);
2696 if (((ic->op == CAST) || (ic->op == '='))
2697 && isOperandEqual(left, IC_RESULT (ic)))
2700 ic = setNextItem (iCodeChain);
2702 /* if casting literal to generic pointer, then cast to rtype instead */
2703 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2705 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2706 ltype = operandType(left);
2709 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2710 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2712 /* find right's definition */
2713 ic = (iCode *) setFirstItem (iCodeChain);
2716 if (((ic->op == CAST) || (ic->op == '='))
2717 && isOperandEqual(right, IC_RESULT (ic)))
2720 ic = setNextItem (iCodeChain);
2722 /* if casting literal to generic pointer, then cast to rtype instead */
2723 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2725 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2726 rtype = operandType(right);
2730 ctype = usualBinaryConversions (&left, &right);
2732 ic = newiCode (op, left, right);
2733 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2735 /* if comparing float
2736 and not a '==' || '!=' || '&&' || '||' (these
2738 if (IS_FLOAT(ctype) &&
2746 return IC_RESULT (ic);
2749 /*-----------------------------------------------------------------*/
2750 /* geniCodeUnary - for a a generic unary operation */
2751 /*-----------------------------------------------------------------*/
2753 geniCodeUnary (operand * op, int oper)
2755 iCode *ic = newiCode (oper, op, NULL);
2757 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2759 return IC_RESULT (ic);
2762 /*-----------------------------------------------------------------*/
2763 /* geniCodeConditional - geniCode for '?' ':' operation */
2764 /*-----------------------------------------------------------------*/
2766 geniCodeConditional (ast * tree,int lvl)
2769 symbol *falseLabel = newiTempLabel (NULL);
2770 symbol *exitLabel = newiTempLabel (NULL);
2771 operand *cond = ast2iCode (tree->left,lvl+1);
2772 operand *true, *false, *result;
2774 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2778 true = ast2iCode (tree->right->left,lvl+1);
2780 /* move the value to a new Operand */
2781 result = newiTempOperand (tree->right->ftype, 0);
2782 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2784 /* generate an unconditional goto */
2785 geniCodeGoto (exitLabel);
2787 /* now for the right side */
2788 geniCodeLabel (falseLabel);
2790 false = ast2iCode (tree->right->right,lvl+1);
2791 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2793 /* create the exit label */
2794 geniCodeLabel (exitLabel);
2799 /*-----------------------------------------------------------------*/
2800 /* geniCodeAssign - generate code for assignment */
2801 /*-----------------------------------------------------------------*/
2803 geniCodeAssign (operand * left, operand * right, int nosupdate)
2806 sym_link *ltype = operandType (left);
2807 sym_link *rtype = operandType (right);
2809 if (!left->isaddr && !IS_ITEMP (left))
2811 werror (E_LVALUE_REQUIRED, "assignment");
2815 /* left is integral type and right is literal then
2816 check if the literal value is within bounds */
2817 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2819 checkConstantRange(ltype,
2820 OP_VALUE(right), "= operation", 0);
2823 /* if the left & right type don't exactly match */
2824 /* if pointer set then make sure the check is
2825 done with the type & not the pointer */
2826 /* then cast rights type to left */
2828 /* first check the type for pointer assignement */
2829 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2830 compareType (ltype, rtype) <= 0)
2832 if (compareType (ltype->next, rtype) < 0)
2833 right = geniCodeCast (ltype->next, right, TRUE);
2835 else if (compareType (ltype, rtype) < 0)
2836 right = geniCodeCast (ltype, right, TRUE);
2838 /* if left is a true symbol & ! volatile
2839 create an assignment to temporary for
2840 the right & then assign this temporary
2841 to the symbol this is SSA . isn't it simple
2842 and folks have published mountains of paper on it */
2843 if (IS_TRUE_SYMOP (left) &&
2844 !isOperandVolatile (left, FALSE) &&
2845 isOperandGlobal (left))
2849 if (IS_TRUE_SYMOP (right))
2850 sym = OP_SYMBOL (right);
2851 ic = newiCode ('=', NULL, right);
2852 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2853 SPIL_LOC (right) = sym;
2857 ic = newiCode ('=', NULL, right);
2858 IC_RESULT (ic) = left;
2861 /* if left isgptr flag is set then support
2862 routine will be required */
2866 ic->nosupdate = nosupdate;
2870 /*-----------------------------------------------------------------*/
2871 /* geniCodeDummyRead - generate code for dummy read */
2872 /*-----------------------------------------------------------------*/
2874 geniCodeDummyRead (operand * op)
2877 sym_link *type = operandType (op);
2879 if (!IS_VOLATILE(type))
2882 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2888 /*-----------------------------------------------------------------*/
2889 /* geniCodeSEParms - generate code for side effecting fcalls */
2890 /*-----------------------------------------------------------------*/
2892 geniCodeSEParms (ast * parms,int lvl)
2897 if (parms->type == EX_OP && parms->opval.op == PARAM)
2899 geniCodeSEParms (parms->left,lvl);
2900 geniCodeSEParms (parms->right,lvl);
2904 /* hack don't like this but too lazy to think of
2906 if (IS_ADDRESS_OF_OP (parms))
2907 parms->left->lvalue = 1;
2909 if (IS_CAST_OP (parms) &&
2910 IS_PTR (parms->ftype) &&
2911 IS_ADDRESS_OF_OP (parms->right))
2912 parms->right->left->lvalue = 1;
2914 parms->opval.oprnd =
2915 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2917 parms->type = EX_OPERAND;
2918 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2919 SPEC_ARGREG(parms->ftype);
2922 /*-----------------------------------------------------------------*/
2923 /* geniCodeParms - generates parameters */
2924 /*-----------------------------------------------------------------*/
2926 geniCodeParms (ast * parms, value *argVals, int *stack,
2927 sym_link * fetype, symbol * func,int lvl)
2935 if (argVals==NULL) {
2937 argVals=FUNC_ARGS(func->type);
2940 /* if this is a param node then do the left & right */
2941 if (parms->type == EX_OP && parms->opval.op == PARAM)
2943 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2944 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2948 /* get the parameter value */
2949 if (parms->type == EX_OPERAND)
2950 pval = parms->opval.oprnd;
2953 /* maybe this else should go away ?? */
2954 /* hack don't like this but too lazy to think of
2956 if (IS_ADDRESS_OF_OP (parms))
2957 parms->left->lvalue = 1;
2959 if (IS_CAST_OP (parms) &&
2960 IS_PTR (parms->ftype) &&
2961 IS_ADDRESS_OF_OP (parms->right))
2962 parms->right->left->lvalue = 1;
2964 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2967 /* if register parm then make it a send */
2968 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2969 IFFUNC_ISBUILTIN(func->type))
2971 ic = newiCode (SEND, pval, NULL);
2972 ic->argreg = SPEC_ARGREG(parms->etype);
2973 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2978 /* now decide whether to push or assign */
2979 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2983 operand *top = operandFromSymbol (argVals->sym);
2984 /* clear useDef and other bitVectors */
2985 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
2986 geniCodeAssign (top, pval, 1);
2990 sym_link *p = operandType (pval);
2992 ic = newiCode (IPUSH, pval, NULL);
2994 /* update the stack adjustment */
2995 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3000 argVals=argVals->next;
3004 /*-----------------------------------------------------------------*/
3005 /* geniCodeCall - generates temp code for calling */
3006 /*-----------------------------------------------------------------*/
3008 geniCodeCall (operand * left, ast * parms,int lvl)
3012 sym_link *type, *etype;
3015 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3016 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3017 werror (E_FUNCTION_EXPECTED);
3021 /* take care of parameters with side-effecting
3022 function calls in them, this is required to take care
3023 of overlaying function parameters */
3024 geniCodeSEParms (parms,lvl);
3026 /* first the parameters */
3027 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3029 /* now call : if symbol then pcall */
3030 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3031 ic = newiCode (PCALL, left, NULL);
3033 ic = newiCode (CALL, left, NULL);
3036 type = copyLinkChain (operandType (left)->next);
3037 etype = getSpec (type);
3038 SPEC_EXTR (etype) = 0;
3039 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3043 /* stack adjustment after call */
3044 ic->parmBytes = stack;
3049 /*-----------------------------------------------------------------*/
3050 /* geniCodeReceive - generate intermediate code for "receive" */
3051 /*-----------------------------------------------------------------*/
3053 geniCodeReceive (value * args)
3055 /* for all arguments that are passed in registers */
3059 if (IS_REGPARM (args->etype))
3061 operand *opr = operandFromValue (args);
3063 symbol *sym = OP_SYMBOL (opr);
3066 /* we will use it after all optimizations
3067 and before liveRange calculation */
3068 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3071 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
3072 options.stackAuto == 0 &&
3073 (!(options.model == MODEL_FLAT24)) )
3078 opl = newiTempOperand (args->type, 0);
3080 sym->reqv->key = sym->key;
3081 OP_SYMBOL (sym->reqv)->key = sym->key;
3082 OP_SYMBOL (sym->reqv)->isreqv = 1;
3083 OP_SYMBOL (sym->reqv)->islocal = 0;
3084 SPIL_LOC (sym->reqv) = sym;
3088 ic = newiCode (RECEIVE, NULL, NULL);
3089 ic->argreg = SPEC_ARGREG(args->etype);
3091 currFunc->recvSize = getSize (sym->type);
3094 IC_RESULT (ic) = opr;
3102 /*-----------------------------------------------------------------*/
3103 /* geniCodeFunctionBody - create the function body */
3104 /*-----------------------------------------------------------------*/
3106 geniCodeFunctionBody (ast * tree,int lvl)
3113 /* reset the auto generation */
3119 func = ast2iCode (tree->left,lvl+1);
3120 fetype = getSpec (operandType (func));
3122 savelineno = lineno;
3123 lineno = OP_SYMBOL (func)->lineDef;
3124 /* create an entry label */
3125 geniCodeLabel (entryLabel);
3126 lineno = savelineno;
3128 /* create a proc icode */
3129 ic = newiCode (FUNCTION, func, NULL);
3130 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3134 /* for all parameters that are passed
3135 on registers add a "receive" */
3136 geniCodeReceive (tree->values.args);
3138 /* generate code for the body */
3139 ast2iCode (tree->right,lvl+1);
3141 /* create a label for return */
3142 geniCodeLabel (returnLabel);
3144 /* now generate the end proc */
3145 ic = newiCode (ENDFUNCTION, func, NULL);
3150 /*-----------------------------------------------------------------*/
3151 /* geniCodeReturn - gen icode for 'return' statement */
3152 /*-----------------------------------------------------------------*/
3154 geniCodeReturn (operand * op)
3158 /* if the operand is present force an rvalue */
3160 op = geniCodeRValue (op, FALSE);
3162 ic = newiCode (RETURN, op, NULL);
3166 /*-----------------------------------------------------------------*/
3167 /* geniCodeIfx - generates code for extended if statement */
3168 /*-----------------------------------------------------------------*/
3170 geniCodeIfx (ast * tree,int lvl)
3173 operand *condition = ast2iCode (tree->left,lvl+1);
3176 /* if condition is null then exit */
3180 condition = geniCodeRValue (condition, FALSE);
3182 cetype = getSpec (operandType (condition));
3183 /* if the condition is a literal */
3184 if (IS_LITERAL (cetype))
3186 if (floatFromVal (condition->operand.valOperand))
3188 if (tree->trueLabel)
3189 geniCodeGoto (tree->trueLabel);
3195 if (tree->falseLabel)
3196 geniCodeGoto (tree->falseLabel);
3203 if (tree->trueLabel)
3205 ic = newiCodeCondition (condition,
3210 if (tree->falseLabel)
3211 geniCodeGoto (tree->falseLabel);
3215 ic = newiCodeCondition (condition,
3222 ast2iCode (tree->right,lvl+1);
3225 /*-----------------------------------------------------------------*/
3226 /* geniCodeJumpTable - tries to create a jump table for switch */
3227 /*-----------------------------------------------------------------*/
3229 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3231 int min = 0, max = 0, t, cnt = 0;
3237 int needRangeCheck = !optimize.noJTabBoundary
3238 || tree->values.switchVals.swDefault;
3240 if (!tree || !caseVals)
3243 /* the criteria for creating a jump table is */
3244 /* all integer numbers between the maximum & minimum must */
3245 /* be present , the maximum value should not exceed 255 */
3246 min = max = (int) floatFromVal (vch = caseVals);
3247 SNPRINTF (buffer, sizeof(buffer),
3249 tree->values.switchVals.swNum,
3251 addSet (&labels, newiTempLabel (buffer));
3253 /* if there is only one case value then no need */
3254 if (!(vch = vch->next))
3259 if (((t = (int) floatFromVal (vch)) - max) != 1)
3261 SNPRINTF (buffer, sizeof(buffer),
3263 tree->values.switchVals.swNum,
3265 addSet (&labels, newiTempLabel (buffer));
3271 /* if the number of case statements <= 2 then */
3272 /* it is not economical to create the jump table */
3273 /* since two compares are needed for boundary conditions */
3274 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3277 if (tree->values.switchVals.swDefault)
3279 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3283 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3287 falseLabel = newiTempLabel (buffer);
3289 /* so we can create a jumptable */
3290 /* first we rule out the boundary conditions */
3291 /* if only optimization says so */
3294 sym_link *cetype = getSpec (operandType (cond));
3295 /* no need to check the lower bound if
3296 the condition is unsigned & minimum value is zero */
3297 if (!(min == 0 && SPEC_USIGN (cetype)))
3299 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3300 ic = newiCodeCondition (boundary, falseLabel, NULL);
3304 /* now for upper bounds */
3305 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3306 ic = newiCodeCondition (boundary, falseLabel, NULL);
3310 /* if the min is not zero then we no make it zero */
3313 cond = geniCodeSubtract (cond, operandFromLit (min));
3314 if (!IS_LITERAL(getSpec(operandType(cond))))
3315 setOperandType (cond, UCHARTYPE);
3318 /* now create the jumptable */
3319 ic = newiCode (JUMPTABLE, NULL, NULL);
3320 IC_JTCOND (ic) = cond;
3321 IC_JTLABELS (ic) = labels;
3326 /*-----------------------------------------------------------------*/
3327 /* geniCodeSwitch - changes a switch to a if statement */
3328 /*-----------------------------------------------------------------*/
3330 geniCodeSwitch (ast * tree,int lvl)
3333 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3334 value *caseVals = tree->values.switchVals.swVals;
3335 symbol *trueLabel, *falseLabel;
3337 /* If the condition is a literal, then just jump to the */
3338 /* appropriate case label. */
3339 if (IS_LITERAL(getSpec(operandType(cond))))
3341 int switchVal, caseVal;
3343 switchVal = (int) floatFromVal (cond->operand.valOperand);
3346 caseVal = (int) floatFromVal (caseVals);
3347 if (caseVal == switchVal)
3349 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3350 tree->values.switchVals.swNum, caseVal);
3351 trueLabel = newiTempLabel (buffer);
3352 geniCodeGoto (trueLabel);
3355 caseVals = caseVals->next;
3357 goto defaultOrBreak;
3360 /* if we can make this a jump table */
3361 if (geniCodeJumpTable (cond, caseVals, tree))
3362 goto jumpTable; /* no need for the comparison */
3364 /* for the cases defined do */
3368 operand *compare = geniCodeLogic (cond,
3369 operandFromValue (caseVals),
3372 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3373 tree->values.switchVals.swNum,
3374 (int) floatFromVal (caseVals));
3375 trueLabel = newiTempLabel (buffer);
3377 ic = newiCodeCondition (compare, trueLabel, NULL);
3379 caseVals = caseVals->next;
3384 /* if default is present then goto break else break */
3385 if (tree->values.switchVals.swDefault)
3387 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3391 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3394 falseLabel = newiTempLabel (buffer);
3395 geniCodeGoto (falseLabel);
3398 ast2iCode (tree->right,lvl+1);
3401 /*-----------------------------------------------------------------*/
3402 /* geniCodeInline - intermediate code for inline assembler */
3403 /*-----------------------------------------------------------------*/
3405 geniCodeInline (ast * tree)
3409 ic = newiCode (INLINEASM, NULL, NULL);
3410 IC_INLINE (ic) = tree->values.inlineasm;
3414 /*-----------------------------------------------------------------*/
3415 /* geniCodeArrayInit - intermediate code for array initializer */
3416 /*-----------------------------------------------------------------*/
3418 geniCodeArrayInit (ast * tree, operand *array)
3422 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3423 ic = newiCode (ARRAYINIT, array, NULL);
3424 IC_ARRAYILIST (ic) = tree->values.constlist;
3426 operand *left=newOperand(), *right=newOperand();
3427 left->type=right->type=SYMBOL;
3428 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3429 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3430 ic = newiCode (ARRAYINIT, left, right);
3435 /*-----------------------------------------------------------------*/
3436 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3437 /* particular case. Ie : assigning or dereferencing array or ptr */
3438 /*-----------------------------------------------------------------*/
3439 set * lvaluereqSet = NULL;
3440 typedef struct lvalItem
3447 /*-----------------------------------------------------------------*/
3448 /* addLvaluereq - add a flag for lvalreq for current ast level */
3449 /*-----------------------------------------------------------------*/
3450 void addLvaluereq(int lvl)
3452 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3455 addSetHead(&lvaluereqSet,lpItem);
3458 /*-----------------------------------------------------------------*/
3459 /* delLvaluereq - del a flag for lvalreq for current ast level */
3460 /*-----------------------------------------------------------------*/
3464 lpItem = getSet(&lvaluereqSet);
3465 if(lpItem) Safe_free(lpItem);
3467 /*-----------------------------------------------------------------*/
3468 /* clearLvaluereq - clear lvalreq flag */
3469 /*-----------------------------------------------------------------*/
3470 void clearLvaluereq()
3473 lpItem = peekSet(lvaluereqSet);
3474 if(lpItem) lpItem->req = 0;
3476 /*-----------------------------------------------------------------*/
3477 /* getLvaluereq - get the last lvalreq level */
3478 /*-----------------------------------------------------------------*/
3479 int getLvaluereqLvl()
3482 lpItem = peekSet(lvaluereqSet);
3483 if(lpItem) return lpItem->lvl;
3486 /*-----------------------------------------------------------------*/
3487 /* isLvaluereq - is lvalreq valid for this level ? */
3488 /*-----------------------------------------------------------------*/
3489 int isLvaluereq(int lvl)
3492 lpItem = peekSet(lvaluereqSet);
3493 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3497 /*-----------------------------------------------------------------*/
3498 /* ast2iCode - creates an icodeList from an ast */
3499 /*-----------------------------------------------------------------*/
3501 ast2iCode (ast * tree,int lvl)
3503 operand *left = NULL;
3504 operand *right = NULL;
3508 /* set the global variables for filename & line number */
3510 filename = tree->filename;
3512 lineno = tree->lineno;
3514 block = tree->block;
3516 scopeLevel = tree->level;
3518 if (tree->type == EX_VALUE)
3519 return operandFromValue (tree->opval.val);
3521 if (tree->type == EX_LINK)
3522 return operandFromLink (tree->opval.lnk);
3524 /* if we find a nullop */
3525 if (tree->type == EX_OP &&
3526 (tree->opval.op == NULLOP ||
3527 tree->opval.op == BLOCK))
3529 if (tree->left && tree->left->type == EX_VALUE)
3530 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3532 ast2iCode (tree->left,lvl+1);
3533 if (tree->right && tree->right->type == EX_VALUE)
3534 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3536 ast2iCode (tree->right,lvl+1);
3540 /* special cases for not evaluating */
3541 if (tree->opval.op != ':' &&
3542 tree->opval.op != '?' &&
3543 tree->opval.op != CALL &&
3544 tree->opval.op != IFX &&
3545 tree->opval.op != LABEL &&
3546 tree->opval.op != GOTO &&
3547 tree->opval.op != SWITCH &&
3548 tree->opval.op != FUNCTION &&
3549 tree->opval.op != INLINEASM)
3552 if (IS_ASSIGN_OP (tree->opval.op) ||
3553 IS_DEREF_OP (tree) ||
3554 (tree->opval.op == '&' && !tree->right) ||
3555 tree->opval.op == PTR_OP)
3558 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3559 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3562 left = operandFromAst (tree->left,lvl);
3564 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3565 left = geniCodeRValue (left, TRUE);
3569 left = operandFromAst (tree->left,lvl);
3571 if (tree->opval.op == INC_OP ||
3572 tree->opval.op == DEC_OP)
3575 right = operandFromAst (tree->right,lvl);
3580 right = operandFromAst (tree->right,lvl);
3584 /* now depending on the type of operand */
3585 /* this will be a biggy */
3586 switch (tree->opval.op)
3589 case '[': /* array operation */
3591 //sym_link *ltype = operandType (left);
3592 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3593 left = geniCodeRValue (left, FALSE);
3594 right = geniCodeRValue (right, TRUE);
3597 return geniCodeArray (left, right,lvl);
3599 case '.': /* structure dereference */
3600 if (IS_PTR (operandType (left)))
3601 left = geniCodeRValue (left, TRUE);
3603 left = geniCodeRValue (left, FALSE);
3605 return geniCodeStruct (left, right, tree->lvalue);
3607 case PTR_OP: /* structure pointer dereference */
3610 pType = operandType (left);
3611 left = geniCodeRValue (left, TRUE);
3613 setOClass (pType, getSpec (operandType (left)));
3616 return geniCodeStruct (left, right, tree->lvalue);
3618 case INC_OP: /* increment operator */
3620 return geniCodePostInc (left);
3622 return geniCodePreInc (right, tree->lvalue);
3624 case DEC_OP: /* decrement operator */
3626 return geniCodePostDec (left);
3628 return geniCodePreDec (right, tree->lvalue);
3630 case '&': /* bitwise and or address of operator */
3632 { /* this is a bitwise operator */
3633 left = geniCodeRValue (left, FALSE);
3634 right = geniCodeRValue (right, FALSE);
3635 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3638 return geniCodeAddressOf (left);
3640 case '|': /* bitwise or & xor */
3642 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3643 geniCodeRValue (right, FALSE),
3648 return geniCodeDivision (geniCodeRValue (left, FALSE),
3649 geniCodeRValue (right, FALSE));
3652 return geniCodeModulus (geniCodeRValue (left, FALSE),
3653 geniCodeRValue (right, FALSE));
3656 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3657 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3659 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3663 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3664 geniCodeRValue (right, FALSE));
3666 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3670 return geniCodeAdd (geniCodeRValue (left, FALSE),
3671 geniCodeRValue (right, FALSE),lvl);
3673 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3676 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3677 geniCodeRValue (right, FALSE));
3680 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3681 geniCodeRValue (right, FALSE));
3683 #if 0 // this indeed needs a second thought
3687 // let's keep this simple: get the rvalue we need
3688 op=geniCodeRValue (right, FALSE);
3689 // now cast it to whatever we want
3690 op=geniCodeCast (operandType(left), op, FALSE);
3691 // if this is going to be used as an lvalue, make it so
3697 #else // bug #604575, is it a bug ????
3698 return geniCodeCast (operandType (left),
3699 geniCodeRValue (right, FALSE), FALSE);
3705 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3710 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3711 setOperandType (op, UCHARTYPE);
3722 /* different compilers (even different gccs) evaluate
3723 the two calls in a different order. to get the same
3724 result on all machines we've to specify a clear sequence.
3725 return geniCodeLogic (geniCodeRValue (left, FALSE),
3726 geniCodeRValue (right, FALSE),
3730 operand *leftOp, *rightOp;
3732 rightOp = geniCodeRValue (right, FALSE);
3733 leftOp = geniCodeRValue (left , FALSE);
3735 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3738 return geniCodeConditional (tree,lvl);
3741 return operandFromLit (getSize (tree->right->ftype));
3745 sym_link *rtype = operandType (right);
3746 sym_link *ltype = operandType (left);
3747 if (IS_PTR (rtype) && IS_ITEMP (right)
3748 && right->isaddr && compareType (rtype->next, ltype) == 1)
3749 right = geniCodeRValue (right, TRUE);
3751 right = geniCodeRValue (right, FALSE);
3753 geniCodeAssign (left, right, 0);
3758 geniCodeAssign (left,
3759 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3761 geniCodeRValue (right, FALSE),FALSE), 0);
3765 geniCodeAssign (left,
3766 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3768 geniCodeRValue (right, FALSE)), 0);
3771 geniCodeAssign (left,
3772 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3774 geniCodeRValue (right, FALSE)), 0);
3777 sym_link *rtype = operandType (right);
3778 sym_link *ltype = operandType (left);
3779 if (IS_PTR (rtype) && IS_ITEMP (right)
3780 && right->isaddr && compareType (rtype->next, ltype) == 1)
3781 right = geniCodeRValue (right, TRUE);
3783 right = geniCodeRValue (right, FALSE);
3786 return geniCodeAssign (left,
3787 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3793 sym_link *rtype = operandType (right);
3794 sym_link *ltype = operandType (left);
3795 if (IS_PTR (rtype) && IS_ITEMP (right)
3796 && right->isaddr && compareType (rtype->next, ltype) == 1)
3798 right = geniCodeRValue (right, TRUE);
3802 right = geniCodeRValue (right, FALSE);
3805 geniCodeAssign (left,
3806 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3812 geniCodeAssign (left,
3813 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3815 geniCodeRValue (right, FALSE)), 0);
3818 geniCodeAssign (left,
3819 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3821 geniCodeRValue (right, FALSE)), 0);
3824 geniCodeAssign (left,
3825 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3827 geniCodeRValue (right, FALSE),
3829 operandType (left)), 0);
3832 geniCodeAssign (left,
3833 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3835 geniCodeRValue (right, FALSE),
3837 operandType (left)), 0);
3840 geniCodeAssign (left,
3841 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3843 geniCodeRValue (right, FALSE),
3845 operandType (left)), 0);
3847 return geniCodeRValue (right, FALSE);
3850 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3853 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3854 return ast2iCode (tree->right,lvl+1);
3857 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3858 return ast2iCode (tree->right,lvl+1);
3861 geniCodeFunctionBody (tree,lvl);
3865 geniCodeReturn (right);
3869 geniCodeIfx (tree,lvl);
3873 geniCodeSwitch (tree,lvl);
3877 geniCodeInline (tree);
3881 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3888 /*-----------------------------------------------------------------*/
3889 /* reverseICChain - gets from the list and creates a linkedlist */
3890 /*-----------------------------------------------------------------*/
3897 while ((loop = getSet (&iCodeChain)))
3909 /*-----------------------------------------------------------------*/
3910 /* iCodeFromAst - given an ast will convert it to iCode */
3911 /*-----------------------------------------------------------------*/
3913 iCodeFromAst (ast * tree)
3915 returnLabel = newiTempLabel ("_return");
3916 entryLabel = newiTempLabel ("_entry");
3918 return reverseiCChain ();
3921 static const char *opTypeToStr(OPTYPE op)
3925 case SYMBOL: return "symbol";
3926 case VALUE: return "value";
3927 case TYPE: return "type";
3929 return "undefined type";
3933 operand *validateOpType(operand *op,
3940 if (op && op->type == type)
3945 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
3946 " expected %s, got %s\n",
3947 macro, args, file, line,
3948 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
3950 return op; // never reached, makes compiler happy.