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 -------------------------------------------------------------------------*/
28 /*-----------------------------------------------------------------*/
29 /* global variables */
31 set *iCodeChain = NULL;
41 symbol *returnLabel; /* function return label */
42 symbol *entryLabel; /* function entry label */
44 #if defined(__BORLANDC__) || defined(_MSC_VER)
45 #define LONG_LONG __int64
47 #define LONG_LONG long long
50 /*-----------------------------------------------------------------*/
51 /* forward definition of some functions */
52 operand *geniCodeDivision (operand *, operand *);
53 operand *geniCodeAssign (operand *, operand *, int);
54 operand *geniCodeArray (operand *, operand *,int);
55 operand *geniCodeArray2Ptr (operand *);
56 operand *geniCodeRValue (operand *, bool);
57 operand *geniCodeDerefPtr (operand *,int);
58 int isLvaluereq(int lvl);
60 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
61 /* forward definition of ic print functions */
62 PRINTFUNC (picGetValueAtAddr);
63 PRINTFUNC (picSetValueAtAddr);
64 PRINTFUNC (picAddrOf);
65 PRINTFUNC (picGeneric);
66 PRINTFUNC (picGenericOne);
68 PRINTFUNC (picAssign);
72 PRINTFUNC (picJumpTable);
73 PRINTFUNC (picInline);
74 PRINTFUNC (picReceive);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
123 /*-----------------------------------------------------------------*/
124 /* checkConstantRange: check a constant against the type */
125 /*-----------------------------------------------------------------*/
127 /* pedantic=0: allmost anything is allowed as long as the absolute
128 value is within the bit range of the type, and -1 is treated as
129 0xf..f for unsigned types (e.g. in assign)
130 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
131 pedantic>1: "char c=200" is not allowed (evaluates to -56)
134 void checkConstantRange(sym_link *ltype, double v, char *msg, int pedantic) {
135 LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype);
136 char message[132]="";
141 // this could be a good idea
142 if (options.pedantic)
148 // if not pedantic: -1 equals to 0xf..f
149 if (SPEC_USIGN(ltype) && (!pedantic ? v!=-1 : 1)) {
155 // if very pedantic: "char c=200" is not allowed
156 if (pedantic>1 && !SPEC_USIGN(ltype)) {
157 max = max/2 + negative;
165 sprintf (message, "for %s %s in %s",
166 SPEC_USIGN(ltype) ? "unsigned" : "signed",
167 nounName(ltype), msg);
168 werror (W_CONST_RANGE, message);
175 /*-----------------------------------------------------------------*/
176 /* operandName - returns the name of the operand */
177 /*-----------------------------------------------------------------*/
179 printOperand (operand * op, FILE * file)
196 opetype = getSpec (operandType (op));
197 if (SPEC_NOUN (opetype) == V_FLOAT)
198 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
200 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
201 printTypeChain (operandType (op), file);
208 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
209 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
211 OP_LIVEFROM (op), OP_LIVETO (op),
212 OP_SYMBOL (op)->stack,
213 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
217 printTypeChain (operandType (op), file);
218 if (SPIL_LOC (op) && IS_ITEMP (op))
219 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
224 /* if assigned to registers */
225 if (OP_SYMBOL (op)->nRegs)
227 if (OP_SYMBOL (op)->isspilt)
229 if (!OP_SYMBOL (op)->remat)
230 if (OP_SYMBOL (op)->usl.spillLoc)
231 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
232 OP_SYMBOL (op)->usl.spillLoc->rname :
233 OP_SYMBOL (op)->usl.spillLoc->name));
235 fprintf (file, "[err]");
237 fprintf (file, "[remat]");
243 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
244 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
249 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
250 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
251 /* if assigned to registers */
252 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
256 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
257 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
258 OP_SYMBOL (op)->regs[i]->name :
267 printTypeChain (op->operand.typeOperand, file);
273 fprintf (file, "\n");
278 /*-----------------------------------------------------------------*/
279 /* print functions */
280 /*-----------------------------------------------------------------*/
281 PRINTFUNC (picGetValueAtAddr)
284 printOperand (IC_RESULT (ic), of);
287 printOperand (IC_LEFT (ic), of);
293 PRINTFUNC (picSetValueAtAddr)
297 printOperand (IC_LEFT (ic), of);
298 fprintf (of, "] = ");
299 printOperand (IC_RIGHT (ic), of);
303 PRINTFUNC (picAddrOf)
306 printOperand (IC_RESULT (ic), of);
307 if (IS_ITEMP (IC_LEFT (ic)))
310 fprintf (of, " = &[");
311 printOperand (IC_LEFT (ic), of);
314 if (IS_ITEMP (IC_LEFT (ic)))
315 fprintf (of, " offsetAdd ");
318 printOperand (IC_RIGHT (ic), of);
320 if (IS_ITEMP (IC_LEFT (ic)))
326 PRINTFUNC (picJumpTable)
331 fprintf (of, "%s\t", s);
332 printOperand (IC_JTCOND (ic), of);
334 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
335 sym = setNextItem (IC_JTLABELS (ic)))
336 fprintf (of, "\t\t\t%s\n", sym->name);
339 PRINTFUNC (picGeneric)
342 printOperand (IC_RESULT (ic), of);
344 printOperand (IC_LEFT (ic), of);
345 fprintf (of, " %s ", s);
346 printOperand (IC_RIGHT (ic), of);
350 PRINTFUNC (picGenericOne)
355 printOperand (IC_RESULT (ic), of);
361 fprintf (of, "%s ", s);
362 printOperand (IC_LEFT (ic), of);
365 if (!IC_RESULT (ic) && !IC_LEFT (ic))
374 printOperand (IC_RESULT (ic), of);
376 printOperand (IC_LEFT (ic), of);
377 printOperand (IC_RIGHT (ic), of);
382 PRINTFUNC (picAssign)
386 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
389 printOperand (IC_RESULT (ic), of);
391 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
394 fprintf (of, " %s ", s);
395 printOperand (IC_RIGHT (ic), of);
402 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
408 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
415 printOperand (IC_COND (ic), of);
418 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
421 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
423 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
427 PRINTFUNC (picInline)
429 fprintf (of, "%s", IC_INLINE (ic));
432 PRINTFUNC (picReceive)
434 printOperand (IC_RESULT (ic), of);
435 fprintf (of, " = %s ", s);
436 printOperand (IC_LEFT (ic), of);
440 /*-----------------------------------------------------------------*/
441 /* piCode - prints one iCode */
442 /*-----------------------------------------------------------------*/
444 piCode (void *item, FILE * of)
452 icTab = getTableEntry (ic->op);
453 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
454 ic->filename, ic->lineno,
455 ic->seq, ic->key, ic->depth, ic->supportRtn);
456 icTab->iCodePrint (of, ic, icTab->printName);
462 printiCChain(ic,stdout);
464 /*-----------------------------------------------------------------*/
465 /* printiCChain - prints intermediate code for humans */
466 /*-----------------------------------------------------------------*/
468 printiCChain (iCode * icChain, FILE * of)
475 for (loop = icChain; loop; loop = loop->next)
477 if ((icTab = getTableEntry (loop->op)))
479 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
480 loop->filename, loop->lineno,
481 loop->seq, loop->key, loop->depth, loop->supportRtn);
483 icTab->iCodePrint (of, loop, icTab->printName);
489 /*-----------------------------------------------------------------*/
490 /* newOperand - allocate, init & return a new iCode */
491 /*-----------------------------------------------------------------*/
497 op = Safe_calloc (1, sizeof (operand));
503 /*-----------------------------------------------------------------*/
504 /* newiCode - create and return a new iCode entry initialised */
505 /*-----------------------------------------------------------------*/
507 newiCode (int op, operand * left, operand * right)
511 ic = Safe_calloc (1, sizeof (iCode));
514 ic->filename = filename;
516 ic->level = scopeLevel;
518 ic->key = iCodeKey++;
520 IC_RIGHT (ic) = right;
525 /*-----------------------------------------------------------------*/
526 /* newiCode for conditional statements */
527 /*-----------------------------------------------------------------*/
529 newiCodeCondition (operand * condition,
535 if (IS_VOID(OP_SYMBOL(condition)->type)) {
536 werror(E_VOID_VALUE_USED);
539 ic = newiCode (IFX, NULL, NULL);
540 IC_COND (ic) = condition;
541 IC_TRUE (ic) = trueLabel;
542 IC_FALSE (ic) = falseLabel;
546 /*-----------------------------------------------------------------*/
547 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
548 /*-----------------------------------------------------------------*/
550 newiCodeLabelGoto (int op, symbol * label)
554 ic = newiCode (op, NULL, NULL);
556 ic->argLabel.label = label;
558 IC_RIGHT (ic) = NULL;
559 IC_RESULT (ic) = NULL;
563 /*-----------------------------------------------------------------*/
564 /* newiTemp - allocate & return a newItemp Variable */
565 /*-----------------------------------------------------------------*/
572 sprintf (buffer, "%s", s);
574 sprintf (buffer, "iTemp%d", iTempNum++);
575 itmp = newSymbol (buffer, 1);
576 strcpy (itmp->rname, itmp->name);
582 /*-----------------------------------------------------------------*/
583 /* newiTempLabel - creates a temp variable label */
584 /*-----------------------------------------------------------------*/
586 newiTempLabel (char *s)
590 /* check if this alredy exists */
591 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
595 itmplbl = newSymbol (s, 1);
598 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
599 itmplbl = newSymbol (buffer, 1);
604 itmplbl->key = labelKey++;
605 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
609 /*-----------------------------------------------------------------*/
610 /* newiTempPreheaderLabel - creates a new preheader label */
611 /*-----------------------------------------------------------------*/
613 newiTempPreheaderLabel ()
617 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
618 itmplbl = newSymbol (buffer, 1);
622 itmplbl->key = labelKey++;
623 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
628 /*-----------------------------------------------------------------*/
629 /* initiCode - initialises some iCode related stuff */
630 /*-----------------------------------------------------------------*/
637 /*-----------------------------------------------------------------*/
638 /* copyiCode - make a copy of the iCode given */
639 /*-----------------------------------------------------------------*/
641 copyiCode (iCode * ic)
643 iCode *nic = newiCode (ic->op, NULL, NULL);
645 nic->lineno = ic->lineno;
646 nic->filename = ic->filename;
647 nic->block = ic->block;
648 nic->level = ic->level;
649 nic->parmBytes = ic->parmBytes;
651 /* deal with the special cases first */
655 IC_COND (nic) = operandFromOperand (IC_COND (ic));
656 IC_TRUE (nic) = IC_TRUE (ic);
657 IC_FALSE (nic) = IC_FALSE (ic);
661 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
662 IC_JTLABELS (nic) = IC_JTLABELS (ic);
667 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
668 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
669 IC_ARGS (nic) = IC_ARGS (ic);
673 IC_INLINE (nic) = IC_INLINE (ic);
677 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
681 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
682 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
683 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
689 /*-----------------------------------------------------------------*/
690 /* getTableEntry - gets the table entry for the given operator */
691 /*-----------------------------------------------------------------*/
693 getTableEntry (int oper)
697 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
698 if (oper == codeTable[i].icode)
699 return &codeTable[i];
704 /*-----------------------------------------------------------------*/
705 /* newiTempOperand - new intermediate temp operand */
706 /*-----------------------------------------------------------------*/
708 newiTempOperand (sym_link * type, char throwType)
711 operand *op = newOperand ();
715 itmp = newiTemp (NULL);
717 etype = getSpec (type);
719 if (IS_LITERAL (etype))
722 /* copy the type information */
724 itmp->etype = getSpec (itmp->type = (throwType ? type :
725 copyLinkChain (type)));
726 if (IS_LITERAL (itmp->etype))
728 SPEC_SCLS (itmp->etype) = S_REGISTER;
729 SPEC_OCLS (itmp->etype) = reg;
732 op->operand.symOperand = itmp;
733 op->key = itmp->key = ++operandKey;
737 /*-----------------------------------------------------------------*/
738 /* operandType - returns the type chain for an operand */
739 /*-----------------------------------------------------------------*/
741 operandType (operand * op)
743 /* depending on type of operand */
748 return op->operand.valOperand->type;
751 return op->operand.symOperand->type;
754 return op->operand.typeOperand;
756 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
757 " operand type not known ");
758 assert (0); /* should never come here */
759 /* Just to keep the compiler happy */
760 return (sym_link *) 0;
764 /*-----------------------------------------------------------------*/
765 /* isParamterToCall - will return 1 if op is a parameter to args */
766 /*-----------------------------------------------------------------*/
768 isParameterToCall (value * args, operand * op)
775 isSymbolEqual (op->operand.symOperand, tval->sym))
782 /*-----------------------------------------------------------------*/
783 /* isOperandGlobal - return 1 if operand is a global variable */
784 /*-----------------------------------------------------------------*/
786 isOperandGlobal (operand * op)
794 if (op->type == SYMBOL &&
795 (op->operand.symOperand->level == 0 ||
796 IS_STATIC (op->operand.symOperand->etype) ||
797 IS_EXTERN (op->operand.symOperand->etype))
804 /*-----------------------------------------------------------------*/
805 /* isOperandVolatile - return 1 if the operand is volatile */
806 /*-----------------------------------------------------------------*/
808 isOperandVolatile (operand * op, bool chkTemp)
813 if (IS_ITEMP (op) && !chkTemp)
816 opetype = getSpec (optype = operandType (op));
818 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
821 if (IS_VOLATILE (opetype))
826 /*-----------------------------------------------------------------*/
827 /* isOperandLiteral - returns 1 if an operand contains a literal */
828 /*-----------------------------------------------------------------*/
830 isOperandLiteral (operand * op)
837 opetype = getSpec (operandType (op));
839 if (IS_LITERAL (opetype))
844 /*-----------------------------------------------------------------*/
845 /* isOperandInFarSpace - will return true if operand is in farSpace */
846 /*-----------------------------------------------------------------*/
848 isOperandInFarSpace (operand * op)
858 if (!IS_TRUE_SYMOP (op))
861 etype = SPIL_LOC (op)->etype;
867 etype = getSpec (operandType (op));
869 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
872 /*-----------------------------------------------------------------*/
873 /* isOperandOnStack - will return true if operand is on stack */
874 /*-----------------------------------------------------------------*/
876 isOperandOnStack (operand * op)
886 etype = getSpec (operandType (op));
888 return ((IN_STACK (etype)) ? TRUE : FALSE);
891 /*-----------------------------------------------------------------*/
892 /* operandLitValue - literal value of an operand */
893 /*-----------------------------------------------------------------*/
895 operandLitValue (operand * op)
897 assert (isOperandLiteral (op));
899 return floatFromVal (op->operand.valOperand);
902 /*-----------------------------------------------------------------*/
903 /* operandOperation - perforoms operations on operands */
904 /*-----------------------------------------------------------------*/
906 operandOperation (operand * left, operand * right,
907 int op, sym_link * type)
909 sym_link *let , *ret=NULL;
910 operand *retval = (operand *) 0;
912 assert (isOperandLiteral (left));
913 let = getSpec(operandType(left));
915 assert (isOperandLiteral (right));
916 ret = getSpec(operandType(left));
922 retval = operandFromValue (valCastLiteral (type,
923 operandLitValue (left) +
924 operandLitValue (right)));
927 retval = operandFromValue (valCastLiteral (type,
928 operandLitValue (left) -
929 operandLitValue (right)));
932 retval = operandFromValue (valCastLiteral (type,
933 operandLitValue (left) *
934 operandLitValue (right)));
937 if ((unsigned long) operandLitValue (right) == 0)
939 werror (E_DIVIDE_BY_ZERO);
944 retval = operandFromValue (valCastLiteral (type,
945 operandLitValue (left) /
946 operandLitValue (right)));
949 if ((unsigned long) operandLitValue (right) == 0) {
950 werror (E_DIVIDE_BY_ZERO);
954 retval = operandFromLit ((SPEC_USIGN(let) ?
955 (unsigned long) operandLitValue (left) :
956 (long) operandLitValue (left)) %
958 (unsigned long) operandLitValue (right) :
959 (long) operandLitValue (right)));
963 retval = operandFromLit (((SPEC_USIGN(let) ?
964 (unsigned long) operandLitValue (left) :
965 (long) operandLitValue (left)) <<
967 (unsigned long) operandLitValue (right) :
968 (long) operandLitValue (right))));
971 retval = operandFromLit (((SPEC_USIGN(let) ?
972 (unsigned long) operandLitValue (left) :
973 (long) operandLitValue (left)) >>
975 (unsigned long) operandLitValue (right) :
976 (long) operandLitValue (right))));
979 retval = operandFromLit (operandLitValue (left) ==
980 operandLitValue (right));
983 retval = operandFromLit (operandLitValue (left) <
984 operandLitValue (right));
987 retval = operandFromLit (operandLitValue (left) <=
988 operandLitValue (right));
991 retval = operandFromLit (operandLitValue (left) !=
992 operandLitValue (right));
995 retval = operandFromLit (operandLitValue (left) >
996 operandLitValue (right));
999 retval = operandFromLit (operandLitValue (left) >=
1000 operandLitValue (right));
1003 retval = operandFromLit ((unsigned long) operandLitValue (left) &
1004 (unsigned long) operandLitValue (right));
1007 retval = operandFromLit ((unsigned long) operandLitValue (left) |
1008 (unsigned long) operandLitValue (right));
1011 retval = operandFromLit ((unsigned long) operandLitValue (left) ^
1012 (unsigned long) operandLitValue (right));
1015 retval = operandFromLit (operandLitValue (left) &&
1016 operandLitValue (right));
1019 retval = operandFromLit (operandLitValue (left) ||
1020 operandLitValue (right));
1024 long i = (long) operandLitValue (left);
1026 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1032 long i = (long) operandLitValue (left);
1034 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1040 retval = operandFromLit (-1 * operandLitValue (left));
1044 retval = operandFromLit (~((long) operandLitValue (left)));
1048 retval = operandFromLit (!operandLitValue (left));
1052 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1053 " operandOperation invalid operator ");
1061 /*-----------------------------------------------------------------*/
1062 /* isOperandEqual - compares two operand & return 1 if they r = */
1063 /*-----------------------------------------------------------------*/
1065 isOperandEqual (operand * left, operand * right)
1067 /* if the pointers are equal then they are equal */
1071 /* if either of them null then false */
1072 if (!left || !right)
1075 if (left->type != right->type)
1078 if (IS_SYMOP (left) && IS_SYMOP (right))
1079 return left->key == right->key;
1081 /* if types are the same */
1085 return isSymbolEqual (left->operand.symOperand,
1086 right->operand.symOperand);
1088 return (floatFromVal (left->operand.valOperand) ==
1089 floatFromVal (right->operand.valOperand));
1091 if (compareType (left->operand.typeOperand,
1092 right->operand.typeOperand) == 1)
1099 /*-----------------------------------------------------------------*/
1100 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1101 /*-----------------------------------------------------------------*/
1103 isiCodeEqual (iCode * left, iCode * right)
1105 /* if the same pointer */
1109 /* if either of them null */
1110 if (!left || !right)
1113 /* if operand are the same */
1114 if (left->op == right->op)
1117 /* compare all the elements depending on type */
1118 if (left->op != IFX)
1120 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1122 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1128 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1130 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1132 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1140 /*-----------------------------------------------------------------*/
1141 /* newiTempFromOp - create a temp Operand with same attributes */
1142 /*-----------------------------------------------------------------*/
1144 newiTempFromOp (operand * op)
1154 nop = newiTempOperand (operandType (op), TRUE);
1155 nop->isaddr = op->isaddr;
1156 nop->isvolatile = op->isvolatile;
1157 nop->isGlobal = op->isGlobal;
1158 nop->isLiteral = op->isLiteral;
1159 nop->usesDefs = op->usesDefs;
1160 nop->isParm = op->isParm;
1164 /*-----------------------------------------------------------------*/
1165 /* operand from operand - creates an operand holder for the type */
1166 /*-----------------------------------------------------------------*/
1168 operandFromOperand (operand * op)
1174 nop = newOperand ();
1175 nop->type = op->type;
1176 nop->isaddr = op->isaddr;
1178 nop->isvolatile = op->isvolatile;
1179 nop->isGlobal = op->isGlobal;
1180 nop->isLiteral = op->isLiteral;
1181 nop->usesDefs = op->usesDefs;
1182 nop->isParm = op->isParm;
1187 nop->operand.symOperand = op->operand.symOperand;
1190 nop->operand.valOperand = op->operand.valOperand;
1193 nop->operand.typeOperand = op->operand.typeOperand;
1200 /*-----------------------------------------------------------------*/
1201 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1202 /*-----------------------------------------------------------------*/
1204 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1206 operand *nop = operandFromOperand (op);
1208 if (nop->type == SYMBOL)
1210 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1211 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1217 /*-----------------------------------------------------------------*/
1218 /* operandFromSymbol - creates an operand from a symbol */
1219 /*-----------------------------------------------------------------*/
1221 operandFromSymbol (symbol * sym)
1226 /* if the symbol's type is a literal */
1227 /* then it is an enumerator type */
1228 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1229 return operandFromValue (valFromType (sym->etype));
1232 sym->key = ++operandKey;
1234 /* if this an implicit variable, means struct/union */
1235 /* member so just return it */
1236 if (sym->implicit || IS_FUNC (sym->type))
1240 op->operand.symOperand = sym;
1242 op->isvolatile = isOperandVolatile (op, TRUE);
1243 op->isGlobal = isOperandGlobal (op);
1247 /* under the following conditions create a
1248 register equivalent for a local symbol */
1249 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1250 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1251 /* (!TARGET_IS_DS390)) && */
1252 (!(options.model == MODEL_FLAT24)) ) &&
1253 options.stackAuto == 0)
1256 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1257 !IS_FUNC (sym->type) && /* not a function */
1258 !sym->_isparm && /* not a parameter */
1259 sym->level && /* is a local variable */
1260 !sym->addrtaken && /* whose address has not been taken */
1261 !sym->reqv && /* does not already have a register euivalence */
1262 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1263 !IS_STATIC (sym->etype) && /* and not declared static */
1264 !sym->islbl && /* not a label */
1265 ok && /* farspace check */
1266 !IS_BITVAR (sym->etype) /* not a bit variable */
1270 /* we will use it after all optimizations
1271 and before liveRange calculation */
1272 sym->reqv = newiTempOperand (sym->type, 0);
1273 sym->reqv->key = sym->key;
1274 OP_SYMBOL (sym->reqv)->key = sym->key;
1275 OP_SYMBOL (sym->reqv)->isreqv = 1;
1276 OP_SYMBOL (sym->reqv)->islocal = 1;
1277 SPIL_LOC (sym->reqv) = sym;
1280 if (!IS_AGGREGATE (sym->type))
1284 op->operand.symOperand = sym;
1287 op->isvolatile = isOperandVolatile (op, TRUE);
1288 op->isGlobal = isOperandGlobal (op);
1289 op->isPtr = IS_PTR (operandType (op));
1290 op->isParm = sym->_isparm;
1295 /* itemp = &[_symbol] */
1297 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1298 IC_LEFT (ic)->type = SYMBOL;
1299 IC_LEFT (ic)->operand.symOperand = sym;
1300 IC_LEFT (ic)->key = sym->key;
1301 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1302 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1303 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1306 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1307 if (IS_ARRAY (sym->type))
1309 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1310 IC_RESULT (ic)->isaddr = 0;
1313 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1315 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1319 return IC_RESULT (ic);
1322 /*-----------------------------------------------------------------*/
1323 /* operandFromValue - creates an operand from value */
1324 /*-----------------------------------------------------------------*/
1326 operandFromValue (value * val)
1330 /* if this is a symbol then do the symbol thing */
1332 return operandFromSymbol (val->sym);
1334 /* this is not a symbol */
1337 op->operand.valOperand = val;
1338 op->isLiteral = isOperandLiteral (op);
1342 /*-----------------------------------------------------------------*/
1343 /* operandFromLink - operand from typeChain */
1344 /*-----------------------------------------------------------------*/
1346 operandFromLink (sym_link * type)
1350 /* operand from sym_link */
1356 op->operand.typeOperand = copyLinkChain (type);
1360 /*-----------------------------------------------------------------*/
1361 /* operandFromLit - makes an operand from a literal value */
1362 /*-----------------------------------------------------------------*/
1364 operandFromLit (double i)
1366 return operandFromValue (valueFromLit (i));
1369 /*-----------------------------------------------------------------*/
1370 /* operandFromAst - creates an operand from an ast */
1371 /*-----------------------------------------------------------------*/
1373 operandFromAst (ast * tree,int lvl)
1379 /* depending on type do */
1383 return ast2iCode (tree,lvl+1);
1387 return operandFromValue (tree->opval.val);
1391 return operandFromLink (tree->opval.lnk);
1395 /* Just to keep the comiler happy */
1396 return (operand *) 0;
1399 /*-----------------------------------------------------------------*/
1400 /* setOperandType - sets the operand's type to the given type */
1401 /*-----------------------------------------------------------------*/
1403 setOperandType (operand * op, sym_link * type)
1405 /* depending on the type of operand */
1410 op->operand.valOperand->etype =
1411 getSpec (op->operand.valOperand->type =
1412 copyLinkChain (type));
1416 if (op->operand.symOperand->isitmp)
1417 op->operand.symOperand->etype =
1418 getSpec (op->operand.symOperand->type =
1419 copyLinkChain (type));
1421 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1422 "attempt to modify type of source");
1426 op->operand.typeOperand = copyLinkChain (type);
1431 /*-----------------------------------------------------------------*/
1432 /* Get size in byte of ptr need to access an array */
1433 /*-----------------------------------------------------------------*/
1435 getArraySizePtr (operand * op)
1437 sym_link *ltype = operandType(op);
1441 int size = getSize(ltype);
1442 return(IS_GENPTR(ltype)?(size-1):size);
1447 sym_link *letype = getSpec(ltype);
1448 switch (PTR_TYPE (SPEC_OCLS (letype)))
1460 return (GPTRSIZE-1);
1469 /*-----------------------------------------------------------------*/
1470 /* perform "usual unary conversions" */
1471 /*-----------------------------------------------------------------*/
1473 usualUnaryConversions (operand * op)
1475 if (IS_INTEGRAL (operandType (op)))
1477 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1480 return geniCodeCast (INTTYPE, op, TRUE);
1486 /*-----------------------------------------------------------------*/
1487 /* perform "usual binary conversions" */
1488 /*-----------------------------------------------------------------*/
1490 usualBinaryConversions (operand ** op1, operand ** op2)
1493 sym_link *rtype = operandType (*op2);
1494 sym_link *ltype = operandType (*op1);
1496 ctype = computeType (ltype, rtype);
1497 *op1 = geniCodeCast (ctype, *op1, TRUE);
1498 *op2 = geniCodeCast (ctype, *op2, TRUE);
1503 /*-----------------------------------------------------------------*/
1504 /* geniCodeValueAtAddress - generate intermeditate code for value */
1506 /*-----------------------------------------------------------------*/
1508 geniCodeRValue (operand * op, bool force)
1511 sym_link *type = operandType (op);
1512 sym_link *etype = getSpec (type);
1514 /* if this is an array & already */
1515 /* an address then return this */
1516 if (IS_AGGREGATE (type) ||
1517 (IS_PTR (type) && !force && !op->isaddr))
1518 return operandFromOperand (op);
1520 /* if this is not an address then must be */
1521 /* rvalue already so return this one */
1525 /* if this is not a temp symbol then */
1526 if (!IS_ITEMP (op) &&
1528 !IN_FARSPACE (SPEC_OCLS (etype)))
1530 op = operandFromOperand (op);
1535 if (IS_SPEC (type) &&
1536 IS_TRUE_SYMOP (op) &&
1537 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1538 /* TARGET_IS_DS390)) */
1539 (options.model == MODEL_FLAT24) ))
1541 op = operandFromOperand (op);
1546 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1547 if (IS_PTR (type) && op->isaddr && force)
1550 type = copyLinkChain (type);
1552 IC_RESULT (ic) = newiTempOperand (type, 1);
1553 IC_RESULT (ic)->isaddr = 0;
1555 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1557 /* if the right is a symbol */
1558 if (op->type == SYMBOL)
1559 IC_RESULT (ic)->operand.symOperand->args =
1560 op->operand.symOperand->args;
1563 return IC_RESULT (ic);
1566 /*-----------------------------------------------------------------*/
1567 /* geniCodeCast - changes the value from one type to another */
1568 /*-----------------------------------------------------------------*/
1570 geniCodeCast (sym_link * type, operand * op, bool implicit)
1574 sym_link *opetype = getSpec (optype = operandType (op));
1577 /* one of them has size zero then error */
1578 if (IS_VOID (optype))
1580 werror (E_CAST_ZERO);
1584 /* if the operand is already the desired type then do nothing */
1585 if (compareType (type, optype) == 1)
1588 /* if this is a literal then just change the type & return */
1589 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1590 return operandFromValue (valCastLiteral (type,
1591 operandLitValue (op)));
1593 /* if casting to some pointer type &&
1594 the destination is not a generic pointer
1595 then give a warning : (only for implicit casts) */
1596 if (IS_PTR (optype) && implicit &&
1597 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1600 werror (W_INCOMPAT_CAST);
1601 fprintf (stderr, "from type '");
1602 printTypeChain (optype, stderr);
1603 fprintf (stderr, "' to type '");
1604 printTypeChain (type, stderr);
1605 fprintf (stderr, "'\n");
1608 /* if they are the same size create an assignment */
1609 if (getSize (type) == getSize (optype) &&
1610 !IS_BITFIELD (type) &&
1612 !IS_FLOAT (optype) &&
1613 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1614 (!IS_SPEC (type) && !IS_SPEC (optype))))
1617 ic = newiCode ('=', NULL, op);
1618 IC_RESULT (ic) = newiTempOperand (type, 0);
1619 SPIL_LOC (IC_RESULT (ic)) =
1620 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1621 IC_RESULT (ic)->isaddr = 0;
1625 ic = newiCode (CAST, operandFromLink (type),
1626 geniCodeRValue (op, FALSE));
1628 IC_RESULT (ic) = newiTempOperand (type, 0);
1631 /* preserve the storage class & output class */
1632 /* of the original variable */
1633 restype = getSpec (operandType (IC_RESULT (ic)));
1634 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1635 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1638 return IC_RESULT (ic);
1641 /*-----------------------------------------------------------------*/
1642 /* geniCodeLabel - will create a Label */
1643 /*-----------------------------------------------------------------*/
1645 geniCodeLabel (symbol * label)
1649 ic = newiCodeLabelGoto (LABEL, label);
1653 /*-----------------------------------------------------------------*/
1654 /* geniCodeGoto - will create a Goto */
1655 /*-----------------------------------------------------------------*/
1657 geniCodeGoto (symbol * label)
1661 ic = newiCodeLabelGoto (GOTO, label);
1665 /*-----------------------------------------------------------------*/
1666 /* geniCodeMultiply - gen intermediate code for multiplication */
1667 /*-----------------------------------------------------------------*/
1669 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1676 /* if they are both literal then we know the result */
1677 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1678 return operandFromValue (valMult (left->operand.valOperand,
1679 right->operand.valOperand));
1681 if (IS_LITERAL(retype)) {
1682 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1685 resType = usualBinaryConversions (&left, &right);
1687 rtype = operandType (right);
1688 retype = getSpec (rtype);
1689 ltype = operandType (left);
1690 letype = getSpec (ltype);
1694 SPEC_NOUN(getSpec(resType))=V_INT;
1697 /* if the right is a literal & power of 2 */
1698 /* then make it a left shift */
1699 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1700 efficient in most cases than 2 bytes result = 2 bytes << literal
1701 if port has 1 byte muldiv */
1702 if (p2 && !IS_FLOAT (letype) &&
1703 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1704 (port->support.muldiv == 1)))
1706 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1708 /* LEFT_OP need same size for left and result, */
1709 left = geniCodeCast (resType, left, TRUE);
1710 ltype = operandType (left);
1712 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1716 ic = newiCode ('*', left, right); /* normal multiplication */
1717 /* if the size left or right > 1 then support routine */
1718 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1722 IC_RESULT (ic) = newiTempOperand (resType, 1);
1725 return IC_RESULT (ic);
1728 /*-----------------------------------------------------------------*/
1729 /* geniCodeDivision - gen intermediate code for division */
1730 /*-----------------------------------------------------------------*/
1732 geniCodeDivision (operand * left, operand * right)
1737 sym_link *rtype = operandType (right);
1738 sym_link *retype = getSpec (rtype);
1739 sym_link *ltype = operandType (left);
1740 sym_link *letype = getSpec (ltype);
1742 resType = usualBinaryConversions (&left, &right);
1744 /* if the right is a literal & power of 2 */
1745 /* then make it a right shift */
1746 if (IS_LITERAL (retype) &&
1747 !IS_FLOAT (letype) &&
1748 (p2 = powof2 ((unsigned long)
1749 floatFromVal (right->operand.valOperand)))) {
1750 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1754 ic = newiCode ('/', left, right); /* normal division */
1755 /* if the size left or right > 1 then support routine */
1756 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1759 IC_RESULT (ic) = newiTempOperand (resType, 0);
1762 return IC_RESULT (ic);
1764 /*-----------------------------------------------------------------*/
1765 /* geniCodeModulus - gen intermediate code for modulus */
1766 /*-----------------------------------------------------------------*/
1768 geniCodeModulus (operand * left, operand * right)
1774 /* if they are both literal then we know the result */
1775 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1776 return operandFromValue (valMod (left->operand.valOperand,
1777 right->operand.valOperand));
1779 resType = usualBinaryConversions (&left, &right);
1781 /* now they are the same size */
1782 ic = newiCode ('%', left, right);
1784 /* if the size left or right > 1 then support routine */
1785 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1787 IC_RESULT (ic) = newiTempOperand (resType, 0);
1790 return IC_RESULT (ic);
1793 /*-----------------------------------------------------------------*/
1794 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1795 /*-----------------------------------------------------------------*/
1797 geniCodePtrPtrSubtract (operand * left, operand * right)
1803 /* if they are both literals then */
1804 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1806 result = operandFromValue (valMinus (left->operand.valOperand,
1807 right->operand.valOperand));
1811 ic = newiCode ('-', left, right);
1813 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1817 return geniCodeDivision (result,
1818 operandFromLit (getSize (ltype->next)));
1821 /*-----------------------------------------------------------------*/
1822 /* geniCodeSubtract - generates code for subtraction */
1823 /*-----------------------------------------------------------------*/
1825 geniCodeSubtract (operand * left, operand * right)
1832 /* if they both pointers then */
1833 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1834 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1835 return geniCodePtrPtrSubtract (left, right);
1837 /* if they are both literal then we know the result */
1838 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1839 && left->isLiteral && right->isLiteral)
1840 return operandFromValue (valMinus (left->operand.valOperand,
1841 right->operand.valOperand));
1843 /* if left is an array or pointer */
1844 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1846 isarray = left->isaddr;
1847 right = geniCodeMultiply (right,
1848 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1849 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1852 { /* make them the same size */
1853 resType = usualBinaryConversions (&left, &right);
1856 ic = newiCode ('-', left, right);
1858 IC_RESULT (ic) = newiTempOperand (resType, 1);
1859 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1861 /* if left or right is a float */
1862 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1866 return IC_RESULT (ic);
1869 /*-----------------------------------------------------------------*/
1870 /* geniCodeAdd - generates iCode for addition */
1871 /*-----------------------------------------------------------------*/
1873 geniCodeAdd (operand * left, operand * right,int lvl)
1881 /* if left is an array then array access */
1882 if (IS_ARRAY (ltype))
1883 return geniCodeArray (left, right,lvl);
1885 /* if the right side is LITERAL zero */
1886 /* return the left side */
1887 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1890 /* if left is literal zero return right */
1891 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1894 /* if left is an array or pointer then size */
1897 isarray = left->isaddr;
1898 // there is no need to multiply with 1
1899 if (getSize(ltype->next)!=1) {
1900 size = operandFromLit (getSize (ltype->next));
1901 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1903 resType = copyLinkChain (ltype);
1906 { /* make them the same size */
1907 resType = usualBinaryConversions (&left, &right);
1910 /* if they are both literals then we know */
1911 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1912 && left->isLiteral && right->isLiteral)
1913 return operandFromValue (valPlus (valFromType (letype),
1914 valFromType (retype)));
1916 ic = newiCode ('+', left, right);
1918 IC_RESULT (ic) = newiTempOperand (resType, 1);
1919 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1921 /* if left or right is a float then support
1923 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1928 return IC_RESULT (ic);
1932 /*-----------------------------------------------------------------*/
1933 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1934 /*-----------------------------------------------------------------*/
1936 aggrToPtr (sym_link * type, bool force)
1942 if (IS_PTR (type) && !force)
1945 etype = getSpec (type);
1949 /* if the output class is generic */
1950 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1951 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1953 /* if the variable was declared a constant */
1954 /* then the pointer points to a constant */
1955 if (IS_CONSTANT (etype))
1956 DCL_PTR_CONST (ptype) = 1;
1958 /* the variable was volatile then pointer to volatile */
1959 if (IS_VOLATILE (etype))
1960 DCL_PTR_VOLATILE (ptype) = 1;
1964 /*-----------------------------------------------------------------*/
1965 /* geniCodeArray2Ptr - array to pointer */
1966 /*-----------------------------------------------------------------*/
1968 geniCodeArray2Ptr (operand * op)
1970 sym_link *optype = operandType (op);
1971 sym_link *opetype = getSpec (optype);
1973 /* set the pointer depending on the storage class */
1974 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1975 DCL_PTR_CONST (optype) = port->mem.code_ro;
1978 /* if the variable was declared a constant */
1979 /* then the pointer points to a constant */
1980 if (IS_CONSTANT (opetype))
1981 DCL_PTR_CONST (optype) = 1;
1983 /* the variable was volatile then pointer to volatile */
1984 if (IS_VOLATILE (opetype))
1985 DCL_PTR_VOLATILE (optype) = 1;
1991 /*-----------------------------------------------------------------*/
1992 /* geniCodeArray - array access */
1993 /*-----------------------------------------------------------------*/
1995 geniCodeArray (operand * left, operand * right,int lvl)
1998 sym_link *ltype = operandType (left);
2002 if (IS_PTR (ltype->next) && left->isaddr)
2004 left = geniCodeRValue (left, FALSE);
2006 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2009 right = geniCodeMultiply (right,
2010 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2012 /* we can check for limits here */
2013 if (isOperandLiteral (right) &&
2016 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2018 werror (E_ARRAY_BOUND);
2019 right = operandFromLit (0);
2022 ic = newiCode ('+', left, right);
2024 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2025 !IS_AGGREGATE (ltype->next) &&
2026 !IS_PTR (ltype->next))
2027 ? ltype : ltype->next), 0);
2029 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2031 return IC_RESULT (ic);
2034 /*-----------------------------------------------------------------*/
2035 /* geniCodeStruct - generates intermediate code for structres */
2036 /*-----------------------------------------------------------------*/
2038 geniCodeStruct (operand * left, operand * right, bool islval)
2041 sym_link *type = operandType (left);
2042 sym_link *etype = getSpec (type);
2044 symbol *element = getStructElement (SPEC_STRUCT (etype),
2045 right->operand.symOperand);
2047 /* add the offset */
2048 ic = newiCode ('+', left, operandFromLit (element->offset));
2050 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2052 /* preserve the storage & output class of the struct */
2053 /* as well as the volatile attribute */
2054 retype = getSpec (operandType (IC_RESULT (ic)));
2055 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2056 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2057 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2059 if (IS_PTR (element->type))
2060 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2062 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2066 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2069 /*-----------------------------------------------------------------*/
2070 /* geniCodePostInc - generate int code for Post increment */
2071 /*-----------------------------------------------------------------*/
2073 geniCodePostInc (operand * op)
2077 sym_link *optype = operandType (op);
2079 operand *rv = (IS_ITEMP (op) ?
2080 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2082 sym_link *rvtype = operandType (rv);
2085 /* if this is not an address we have trouble */
2088 werror (E_LVALUE_REQUIRED, "++");
2092 rOp = newiTempOperand (rvtype, 0);
2093 OP_SYMBOL(rOp)->noSpilLoc = 1;
2096 OP_SYMBOL(rv)->noSpilLoc = 1;
2098 geniCodeAssign (rOp, rv, 0);
2100 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2101 if (IS_FLOAT (rvtype))
2102 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2104 ic = newiCode ('+', rv, operandFromLit (size));
2106 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2109 geniCodeAssign (op, result, 0);
2115 /*-----------------------------------------------------------------*/
2116 /* geniCodePreInc - generate code for preIncrement */
2117 /*-----------------------------------------------------------------*/
2119 geniCodePreInc (operand * op)
2122 sym_link *optype = operandType (op);
2123 operand *rop = (IS_ITEMP (op) ?
2124 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2126 sym_link *roptype = operandType (rop);
2132 werror (E_LVALUE_REQUIRED, "++");
2137 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2138 if (IS_FLOAT (roptype))
2139 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2141 ic = newiCode ('+', rop, operandFromLit (size));
2142 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2146 return geniCodeAssign (op, result, 0);
2149 /*-----------------------------------------------------------------*/
2150 /* geniCodePostDec - generates code for Post decrement */
2151 /*-----------------------------------------------------------------*/
2153 geniCodePostDec (operand * op)
2157 sym_link *optype = operandType (op);
2159 operand *rv = (IS_ITEMP (op) ?
2160 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2162 sym_link *rvtype = operandType (rv);
2165 /* if this is not an address we have trouble */
2168 werror (E_LVALUE_REQUIRED, "--");
2172 rOp = newiTempOperand (rvtype, 0);
2173 OP_SYMBOL(rOp)->noSpilLoc = 1;
2176 OP_SYMBOL(rv)->noSpilLoc = 1;
2178 geniCodeAssign (rOp, rv, 0);
2180 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2181 if (IS_FLOAT (rvtype))
2182 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2184 ic = newiCode ('-', rv, operandFromLit (size));
2186 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2189 geniCodeAssign (op, result, 0);
2195 /*-----------------------------------------------------------------*/
2196 /* geniCodePreDec - generate code for pre decrement */
2197 /*-----------------------------------------------------------------*/
2199 geniCodePreDec (operand * op)
2202 sym_link *optype = operandType (op);
2203 operand *rop = (IS_ITEMP (op) ?
2204 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2206 sym_link *roptype = operandType (rop);
2212 werror (E_LVALUE_REQUIRED, "--");
2217 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2218 if (IS_FLOAT (roptype))
2219 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2221 ic = newiCode ('-', rop, operandFromLit (size));
2222 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2226 return geniCodeAssign (op, result, 0);
2230 /*-----------------------------------------------------------------*/
2231 /* geniCodeBitwise - gen int code for bitWise operators */
2232 /*-----------------------------------------------------------------*/
2234 geniCodeBitwise (operand * left, operand * right,
2235 int oper, sym_link * resType)
2239 left = geniCodeCast (resType, left, TRUE);
2240 right = geniCodeCast (resType, right, TRUE);
2242 ic = newiCode (oper, left, right);
2243 IC_RESULT (ic) = newiTempOperand (resType, 0);
2246 return IC_RESULT (ic);
2249 /*-----------------------------------------------------------------*/
2250 /* geniCodeAddressOf - gens icode for '&' address of operator */
2251 /*-----------------------------------------------------------------*/
2253 geniCodeAddressOf (operand * op)
2257 sym_link *optype = operandType (op);
2258 sym_link *opetype = getSpec (optype);
2260 /* lvalue check already done in decorateType */
2261 /* this must be a lvalue */
2262 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2263 /* werror (E_LVALUE_REQUIRED,"&"); */
2268 p->class = DECLARATOR;
2270 /* set the pointer depending on the storage class */
2271 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2272 DCL_PTR_CONST (p) = port->mem.code_ro;
2274 /* make sure we preserve the const & volatile */
2275 if (IS_CONSTANT (opetype))
2276 DCL_PTR_CONST (p) = 1;
2278 if (IS_VOLATILE (opetype))
2279 DCL_PTR_VOLATILE (p) = 1;
2281 p->next = copyLinkChain (optype);
2283 /* if already a temp */
2286 setOperandType (op, p);
2291 /* other wise make this of the type coming in */
2292 ic = newiCode (ADDRESS_OF, op, NULL);
2293 IC_RESULT (ic) = newiTempOperand (p, 1);
2294 IC_RESULT (ic)->isaddr = 0;
2296 return IC_RESULT (ic);
2298 /*-----------------------------------------------------------------*/
2299 /* setOClass - sets the output class depending on the pointer type */
2300 /*-----------------------------------------------------------------*/
2302 setOClass (sym_link * ptr, sym_link * spec)
2304 switch (DCL_TYPE (ptr))
2307 SPEC_OCLS (spec) = data;
2311 SPEC_OCLS (spec) = generic;
2315 SPEC_OCLS (spec) = xdata;
2319 SPEC_OCLS (spec) = code;
2323 SPEC_OCLS (spec) = idata;
2327 SPEC_OCLS (spec) = xstack;
2331 SPEC_OCLS (spec) = eeprom;
2340 /*-----------------------------------------------------------------*/
2341 /* geniCodeDerefPtr - dereference pointer with '*' */
2342 /*-----------------------------------------------------------------*/
2344 geniCodeDerefPtr (operand * op,int lvl)
2346 sym_link *rtype, *retype;
2347 sym_link *optype = operandType (op);
2349 /* if this is a pointer then generate the rvalue */
2350 if (IS_PTR (optype))
2352 if (IS_TRUE_SYMOP (op))
2355 op = geniCodeRValue (op, TRUE);
2358 op = geniCodeRValue (op, TRUE);
2361 /* now get rid of the pointer part */
2362 if (isLvaluereq(lvl) && IS_ITEMP (op))
2364 retype = getSpec (rtype = copyLinkChain (optype));
2368 retype = getSpec (rtype = copyLinkChain (optype->next));
2371 /* if this is a pointer then outputclass needs 2b updated */
2372 if (IS_PTR (optype))
2373 setOClass (optype, retype);
2375 op->isGptr = IS_GENPTR (optype);
2377 /* if the pointer was declared as a constant */
2378 /* then we cannot allow assignment to the derefed */
2379 if (IS_PTR_CONST (optype))
2380 SPEC_CONST (retype) = 1;
2382 op->isaddr = (IS_PTR (rtype) ||
2383 IS_STRUCT (rtype) ||
2388 if (!isLvaluereq(lvl))
2389 op = geniCodeRValue (op, TRUE);
2391 setOperandType (op, rtype);
2396 /*-----------------------------------------------------------------*/
2397 /* geniCodeUnaryMinus - does a unary minus of the operand */
2398 /*-----------------------------------------------------------------*/
2400 geniCodeUnaryMinus (operand * op)
2403 sym_link *optype = operandType (op);
2405 if (IS_LITERAL (optype))
2406 return operandFromLit (-floatFromVal (op->operand.valOperand));
2408 ic = newiCode (UNARYMINUS, op, NULL);
2409 IC_RESULT (ic) = newiTempOperand (optype, 0);
2411 return IC_RESULT (ic);
2414 /*-----------------------------------------------------------------*/
2415 /* geniCodeLeftShift - gen i code for left shift */
2416 /*-----------------------------------------------------------------*/
2418 geniCodeLeftShift (operand * left, operand * right)
2422 ic = newiCode (LEFT_OP, left, right);
2423 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2425 return IC_RESULT (ic);
2428 /*-----------------------------------------------------------------*/
2429 /* geniCodeRightShift - gen i code for right shift */
2430 /*-----------------------------------------------------------------*/
2432 geniCodeRightShift (operand * left, operand * right)
2436 ic = newiCode (RIGHT_OP, left, right);
2437 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2439 return IC_RESULT (ic);
2442 /*-----------------------------------------------------------------*/
2443 /* geniCodeLogic- logic code */
2444 /*-----------------------------------------------------------------*/
2446 geniCodeLogic (operand * left, operand * right, int op)
2450 sym_link *rtype = operandType (right);
2451 sym_link *ltype = operandType (left);
2453 /* left is integral type and right is literal then
2454 check if the literal value is within bounds */
2455 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2457 checkConstantRange(ltype,
2458 operandLitValue(right), "compare operation", 1);
2461 ctype = usualBinaryConversions (&left, &right);
2463 ic = newiCode (op, left, right);
2464 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2466 /* if comparing float
2467 and not a '==' || '!=' || '&&' || '||' (these
2469 if (IS_FLOAT(ctype) &&
2477 return IC_RESULT (ic);
2480 /*-----------------------------------------------------------------*/
2481 /* geniCodeUnary - for a a generic unary operation */
2482 /*-----------------------------------------------------------------*/
2484 geniCodeUnary (operand * op, int oper)
2486 iCode *ic = newiCode (oper, op, NULL);
2488 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2490 return IC_RESULT (ic);
2493 /*-----------------------------------------------------------------*/
2494 /* geniCodeConditional - geniCode for '?' ':' operation */
2495 /*-----------------------------------------------------------------*/
2497 geniCodeConditional (ast * tree,int lvl)
2500 symbol *falseLabel = newiTempLabel (NULL);
2501 symbol *exitLabel = newiTempLabel (NULL);
2502 operand *cond = ast2iCode (tree->left,lvl+1);
2503 operand *true, *false, *result;
2505 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2509 true = ast2iCode (tree->right->left,lvl+1);
2511 /* move the value to a new Operand */
2512 result = newiTempOperand (operandType (true), 0);
2513 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2515 /* generate an unconditional goto */
2516 geniCodeGoto (exitLabel);
2518 /* now for the right side */
2519 geniCodeLabel (falseLabel);
2521 false = ast2iCode (tree->right->right,lvl+1);
2522 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2524 /* create the exit label */
2525 geniCodeLabel (exitLabel);
2530 /*-----------------------------------------------------------------*/
2531 /* geniCodeAssign - generate code for assignment */
2532 /*-----------------------------------------------------------------*/
2534 geniCodeAssign (operand * left, operand * right, int nosupdate)
2537 sym_link *ltype = operandType (left);
2538 sym_link *rtype = operandType (right);
2540 if (!left->isaddr && !IS_ITEMP (left))
2542 werror (E_LVALUE_REQUIRED, "assignment");
2546 /* left is integral type and right is literal then
2547 check if the literal value is within bounds */
2548 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2550 checkConstantRange(ltype,
2551 operandLitValue(right), "= operation", 0);
2554 /* if the left & right type don't exactly match */
2555 /* if pointer set then make sure the check is
2556 done with the type & not the pointer */
2557 /* then cast rights type to left */
2559 /* first check the type for pointer assignement */
2560 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2561 compareType (ltype, rtype) < 0)
2563 if (compareType (ltype->next, rtype) < 0)
2564 right = geniCodeCast (ltype->next, right, TRUE);
2566 else if (compareType (ltype, rtype) < 0)
2567 right = geniCodeCast (ltype, right, TRUE);
2569 /* if left is a true symbol & ! volatile
2570 create an assignment to temporary for
2571 the right & then assign this temporary
2572 to the symbol this is SSA . isn't it simple
2573 and folks have published mountains of paper on it */
2574 if (IS_TRUE_SYMOP (left) &&
2575 !isOperandVolatile (left, FALSE) &&
2576 isOperandGlobal (left))
2580 if (IS_TRUE_SYMOP (right))
2581 sym = OP_SYMBOL (right);
2582 ic = newiCode ('=', NULL, right);
2583 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2584 SPIL_LOC (right) = sym;
2588 ic = newiCode ('=', NULL, right);
2589 IC_RESULT (ic) = left;
2592 /* if left isgptr flag is set then support
2593 routine will be required */
2597 ic->nosupdate = nosupdate;
2601 /*-----------------------------------------------------------------*/
2602 /* geniCodeSEParms - generate code for side effecting fcalls */
2603 /*-----------------------------------------------------------------*/
2605 geniCodeSEParms (ast * parms,int lvl)
2610 if (parms->type == EX_OP && parms->opval.op == PARAM)
2612 geniCodeSEParms (parms->left,lvl);
2613 geniCodeSEParms (parms->right,lvl);
2617 /* hack don't like this but too lazy to think of
2619 if (IS_ADDRESS_OF_OP (parms))
2620 parms->left->lvalue = 1;
2622 if (IS_CAST_OP (parms) &&
2623 IS_PTR (parms->ftype) &&
2624 IS_ADDRESS_OF_OP (parms->right))
2625 parms->right->left->lvalue = 1;
2627 parms->opval.oprnd =
2628 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2630 parms->type = EX_OPERAND;
2633 /*-----------------------------------------------------------------*/
2634 /* geniCodeParms - generates parameters */
2635 /*-----------------------------------------------------------------*/
2637 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2645 /* if this is a param node then do the left & right */
2646 if (parms->type == EX_OP && parms->opval.op == PARAM)
2648 geniCodeParms (parms->left, stack, fetype, func,lvl);
2649 geniCodeParms (parms->right, stack, fetype, func,lvl);
2653 /* get the parameter value */
2654 if (parms->type == EX_OPERAND)
2655 pval = parms->opval.oprnd;
2658 /* maybe this else should go away ?? */
2659 /* hack don't like this but too lazy to think of
2661 if (IS_ADDRESS_OF_OP (parms))
2662 parms->left->lvalue = 1;
2664 if (IS_CAST_OP (parms) &&
2665 IS_PTR (parms->ftype) &&
2666 IS_ADDRESS_OF_OP (parms->right))
2667 parms->right->left->lvalue = 1;
2669 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2672 /* if register parm then make it a send */
2673 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2674 IS_REGPARM (parms->etype)) && !func->hasVargs)
2676 ic = newiCode (SEND, pval, NULL);
2681 /* now decide whether to push or assign */
2682 if (!(options.stackAuto || IS_RENT (fetype)))
2686 operand *top = operandFromSymbol (parms->argSym);
2687 geniCodeAssign (top, pval, 1);
2691 sym_link *p = operandType (pval);
2693 ic = newiCode (IPUSH, pval, NULL);
2695 /* update the stack adjustment */
2696 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2703 /*-----------------------------------------------------------------*/
2704 /* geniCodeCall - generates temp code for calling */
2705 /*-----------------------------------------------------------------*/
2707 geniCodeCall (operand * left, ast * parms,int lvl)
2711 sym_link *type, *etype;
2714 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2715 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2716 werror (E_FUNCTION_EXPECTED);
2720 /* take care of parameters with side-effecting
2721 function calls in them, this is required to take care
2722 of overlaying function parameters */
2723 geniCodeSEParms (parms,lvl);
2725 /* first the parameters */
2726 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2728 /* now call : if symbol then pcall */
2729 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2730 ic = newiCode (PCALL, left, NULL);
2732 ic = newiCode (CALL, left, NULL);
2734 IC_ARGS (ic) = left->operand.symOperand->args;
2735 type = copyLinkChain (operandType (left)->next);
2736 etype = getSpec (type);
2737 SPEC_EXTR (etype) = 0;
2738 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2742 /* stack adjustment after call */
2743 ic->parmBytes = stack;
2748 /*-----------------------------------------------------------------*/
2749 /* geniCodeReceive - generate intermediate code for "receive" */
2750 /*-----------------------------------------------------------------*/
2752 geniCodeReceive (value * args)
2754 /* for all arguments that are passed in registers */
2758 if (IS_REGPARM (args->etype))
2760 operand *opr = operandFromValue (args);
2762 symbol *sym = OP_SYMBOL (opr);
2765 /* we will use it after all optimizations
2766 and before liveRange calculation */
2767 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2770 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2771 options.stackAuto == 0 &&
2772 /* !TARGET_IS_DS390) */
2773 (!(options.model == MODEL_FLAT24)) )
2778 opl = newiTempOperand (args->type, 0);
2780 sym->reqv->key = sym->key;
2781 OP_SYMBOL (sym->reqv)->key = sym->key;
2782 OP_SYMBOL (sym->reqv)->isreqv = 1;
2783 OP_SYMBOL (sym->reqv)->islocal = 0;
2784 SPIL_LOC (sym->reqv) = sym;
2788 ic = newiCode (RECEIVE, NULL, NULL);
2789 currFunc->recvSize = getSize (sym->etype);
2790 IC_RESULT (ic) = opr;
2798 /*-----------------------------------------------------------------*/
2799 /* geniCodeFunctionBody - create the function body */
2800 /*-----------------------------------------------------------------*/
2802 geniCodeFunctionBody (ast * tree,int lvl)
2809 /* reset the auto generation */
2815 func = ast2iCode (tree->left,lvl+1);
2816 fetype = getSpec (operandType (func));
2818 savelineno = lineno;
2819 lineno = OP_SYMBOL (func)->lineDef;
2820 /* create an entry label */
2821 geniCodeLabel (entryLabel);
2822 lineno = savelineno;
2824 /* create a proc icode */
2825 ic = newiCode (FUNCTION, func, NULL);
2826 /* if the function has parmas then */
2827 /* save the parameters information */
2828 ic->argLabel.args = tree->values.args;
2829 ic->lineno = OP_SYMBOL (func)->lineDef;
2833 /* for all parameters that are passed
2834 on registers add a "receive" */
2835 geniCodeReceive (tree->values.args);
2837 /* generate code for the body */
2838 ast2iCode (tree->right,lvl+1);
2840 /* create a label for return */
2841 geniCodeLabel (returnLabel);
2843 /* now generate the end proc */
2844 ic = newiCode (ENDFUNCTION, func, NULL);
2849 /*-----------------------------------------------------------------*/
2850 /* geniCodeReturn - gen icode for 'return' statement */
2851 /*-----------------------------------------------------------------*/
2853 geniCodeReturn (operand * op)
2857 /* if the operand is present force an rvalue */
2859 op = geniCodeRValue (op, FALSE);
2861 ic = newiCode (RETURN, op, NULL);
2865 /*-----------------------------------------------------------------*/
2866 /* geniCodeIfx - generates code for extended if statement */
2867 /*-----------------------------------------------------------------*/
2869 geniCodeIfx (ast * tree,int lvl)
2872 operand *condition = ast2iCode (tree->left,lvl+1);
2875 /* if condition is null then exit */
2879 condition = geniCodeRValue (condition, FALSE);
2881 cetype = getSpec (operandType (condition));
2882 /* if the condition is a literal */
2883 if (IS_LITERAL (cetype))
2885 if (floatFromVal (condition->operand.valOperand))
2887 if (tree->trueLabel)
2888 geniCodeGoto (tree->trueLabel);
2894 if (tree->falseLabel)
2895 geniCodeGoto (tree->falseLabel);
2902 if (tree->trueLabel)
2904 ic = newiCodeCondition (condition,
2909 if (tree->falseLabel)
2910 geniCodeGoto (tree->falseLabel);
2914 ic = newiCodeCondition (condition,
2921 ast2iCode (tree->right,lvl+1);
2924 /*-----------------------------------------------------------------*/
2925 /* geniCodeJumpTable - tries to create a jump table for switch */
2926 /*-----------------------------------------------------------------*/
2928 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2930 int min = 0, max = 0, t, cnt = 0;
2937 if (!tree || !caseVals)
2940 /* the criteria for creating a jump table is */
2941 /* all integer numbers between the maximum & minimum must */
2942 /* be present , the maximum value should not exceed 255 */
2943 min = max = (int) floatFromVal (vch = caseVals);
2944 sprintf (buffer, "_case_%d_%d",
2945 tree->values.switchVals.swNum,
2947 addSet (&labels, newiTempLabel (buffer));
2949 /* if there is only one case value then no need */
2950 if (!(vch = vch->next))
2955 if (((t = (int) floatFromVal (vch)) - max) != 1)
2957 sprintf (buffer, "_case_%d_%d",
2958 tree->values.switchVals.swNum,
2960 addSet (&labels, newiTempLabel (buffer));
2966 /* if the number of case statements <= 2 then */
2967 /* it is not economical to create the jump table */
2968 /* since two compares are needed for boundary conditions */
2969 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2972 if (tree->values.switchVals.swDefault)
2973 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2975 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2977 falseLabel = newiTempLabel (buffer);
2979 /* so we can create a jumptable */
2980 /* first we rule out the boundary conditions */
2981 /* if only optimization says so */
2982 if (!optimize.noJTabBoundary)
2984 sym_link *cetype = getSpec (operandType (cond));
2985 /* no need to check the lower bound if
2986 the condition is unsigned & minimum value is zero */
2987 if (!(min == 0 && SPEC_USIGN (cetype)))
2989 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2990 ic = newiCodeCondition (boundary, falseLabel, NULL);
2994 /* now for upper bounds */
2995 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
2996 ic = newiCodeCondition (boundary, falseLabel, NULL);
3000 /* if the min is not zero then we no make it zero */
3003 cond = geniCodeSubtract (cond, operandFromLit (min));
3004 setOperandType (cond, UCHARTYPE);
3007 /* now create the jumptable */
3008 ic = newiCode (JUMPTABLE, NULL, NULL);
3009 IC_JTCOND (ic) = cond;
3010 IC_JTLABELS (ic) = labels;
3015 /*-----------------------------------------------------------------*/
3016 /* geniCodeSwitch - changes a switch to a if statement */
3017 /*-----------------------------------------------------------------*/
3019 geniCodeSwitch (ast * tree,int lvl)
3022 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3023 value *caseVals = tree->values.switchVals.swVals;
3024 symbol *trueLabel, *falseLabel;
3026 /* if we can make this a jump table */
3027 if (geniCodeJumpTable (cond, caseVals, tree))
3028 goto jumpTable; /* no need for the comparison */
3030 /* for the cases defined do */
3034 operand *compare = geniCodeLogic (cond,
3035 operandFromValue (caseVals),
3038 sprintf (buffer, "_case_%d_%d",
3039 tree->values.switchVals.swNum,
3040 (int) floatFromVal (caseVals));
3041 trueLabel = newiTempLabel (buffer);
3043 ic = newiCodeCondition (compare, trueLabel, NULL);
3045 caseVals = caseVals->next;
3050 /* if default is present then goto break else break */
3051 if (tree->values.switchVals.swDefault)
3052 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3054 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3056 falseLabel = newiTempLabel (buffer);
3057 geniCodeGoto (falseLabel);
3060 ast2iCode (tree->right,lvl+1);
3063 /*-----------------------------------------------------------------*/
3064 /* geniCodeInline - intermediate code for inline assembler */
3065 /*-----------------------------------------------------------------*/
3067 geniCodeInline (ast * tree)
3071 ic = newiCode (INLINEASM, NULL, NULL);
3072 IC_INLINE (ic) = tree->values.inlineasm;
3076 /*-----------------------------------------------------------------*/
3077 /* geniCodeArrayInit - intermediate code for array initializer */
3078 /*-----------------------------------------------------------------*/
3080 geniCodeArrayInit (ast * tree, operand *array)
3084 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3085 ic = newiCode (ARRAYINIT, array, NULL);
3086 IC_ARRAYILIST (ic) = tree->values.constlist;
3088 operand *left=newOperand(), *right=newOperand();
3089 left->type=right->type=SYMBOL;
3090 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3091 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3092 ic = newiCode (ARRAYINIT, left, right);
3097 /*-----------------------------------------------------------------*/
3098 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3099 /* particular case. Ie : assigning or dereferencing array or ptr */
3100 /*-----------------------------------------------------------------*/
3101 set * lvaluereqSet = NULL;
3102 typedef struct lvalItem
3109 /*-----------------------------------------------------------------*/
3110 /* addLvaluereq - add a flag for lvalreq for current ast level */
3111 /*-----------------------------------------------------------------*/
3112 void addLvaluereq(int lvl)
3114 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3117 addSetHead(&lvaluereqSet,lpItem);
3120 /*-----------------------------------------------------------------*/
3121 /* delLvaluereq - del a flag for lvalreq for current ast level */
3122 /*-----------------------------------------------------------------*/
3126 lpItem = getSet(&lvaluereqSet);
3127 if(lpItem) free(lpItem);
3129 /*-----------------------------------------------------------------*/
3130 /* clearLvaluereq - clear lvalreq flag */
3131 /*-----------------------------------------------------------------*/
3132 void clearLvaluereq()
3135 lpItem = peekSet(lvaluereqSet);
3136 if(lpItem) lpItem->req = 0;
3138 /*-----------------------------------------------------------------*/
3139 /* getLvaluereq - get the last lvalreq level */
3140 /*-----------------------------------------------------------------*/
3141 int getLvaluereqLvl()
3144 lpItem = peekSet(lvaluereqSet);
3145 if(lpItem) return lpItem->lvl;
3148 /*-----------------------------------------------------------------*/
3149 /* isLvaluereq - is lvalreq valid for this level ? */
3150 /*-----------------------------------------------------------------*/
3151 int isLvaluereq(int lvl)
3154 lpItem = peekSet(lvaluereqSet);
3155 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3159 /*-----------------------------------------------------------------*/
3160 /* ast2iCode - creates an icodeList from an ast */
3161 /*-----------------------------------------------------------------*/
3163 ast2iCode (ast * tree,int lvl)
3165 operand *left = NULL;
3166 operand *right = NULL;
3169 /* set the global variables for filename & line number */
3171 filename = tree->filename;
3173 lineno = tree->lineno;
3175 block = tree->block;
3177 scopeLevel = tree->level;
3179 if (tree->type == EX_VALUE)
3180 return operandFromValue (tree->opval.val);
3182 if (tree->type == EX_LINK)
3183 return operandFromLink (tree->opval.lnk);
3185 /* if we find a nullop */
3186 if (tree->type == EX_OP &&
3187 (tree->opval.op == NULLOP ||
3188 tree->opval.op == BLOCK))
3190 ast2iCode (tree->left,lvl+1);
3191 ast2iCode (tree->right,lvl+1);
3195 /* special cases for not evaluating */
3196 if (tree->opval.op != ':' &&
3197 tree->opval.op != '?' &&
3198 tree->opval.op != CALL &&
3199 tree->opval.op != IFX &&
3200 tree->opval.op != LABEL &&
3201 tree->opval.op != GOTO &&
3202 tree->opval.op != SWITCH &&
3203 tree->opval.op != FUNCTION &&
3204 tree->opval.op != INLINEASM)
3207 if (IS_ASSIGN_OP (tree->opval.op) ||
3208 IS_DEREF_OP (tree) ||
3209 (tree->opval.op == '&' && !tree->right) ||
3210 tree->opval.op == PTR_OP)
3213 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3214 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3217 left = operandFromAst (tree->left,lvl);
3219 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3220 left = geniCodeRValue (left, TRUE);
3224 left = operandFromAst (tree->left,lvl);
3226 if (tree->opval.op == INC_OP ||
3227 tree->opval.op == DEC_OP)
3230 right = operandFromAst (tree->right,lvl);
3235 right = operandFromAst (tree->right,lvl);
3239 /* now depending on the type of operand */
3240 /* this will be a biggy */
3241 switch (tree->opval.op)
3244 case '[': /* array operation */
3246 sym_link *ltype = operandType (left);
3247 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3248 right = geniCodeRValue (right, TRUE);
3251 return geniCodeArray (left, right,lvl);
3253 case '.': /* structure dereference */
3254 if (IS_PTR (operandType (left)))
3255 left = geniCodeRValue (left, TRUE);
3257 left = geniCodeRValue (left, FALSE);
3259 return geniCodeStruct (left, right, tree->lvalue);
3261 case PTR_OP: /* structure pointer dereference */
3264 pType = operandType (left);
3265 left = geniCodeRValue (left, TRUE);
3267 setOClass (pType, getSpec (operandType (left)));
3270 return geniCodeStruct (left, right, tree->lvalue);
3272 case INC_OP: /* increment operator */
3274 return geniCodePostInc (left);
3276 return geniCodePreInc (right);
3278 case DEC_OP: /* decrement operator */
3280 return geniCodePostDec (left);
3282 return geniCodePreDec (right);
3284 case '&': /* bitwise and or address of operator */
3286 { /* this is a bitwise operator */
3287 left = geniCodeRValue (left, FALSE);
3288 right = geniCodeRValue (right, FALSE);
3289 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3292 return geniCodeAddressOf (left);
3294 case '|': /* bitwise or & xor */
3296 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3297 geniCodeRValue (right, FALSE),
3302 return geniCodeDivision (geniCodeRValue (left, FALSE),
3303 geniCodeRValue (right, FALSE));
3306 return geniCodeModulus (geniCodeRValue (left, FALSE),
3307 geniCodeRValue (right, FALSE));
3310 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3311 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3313 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3317 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3318 geniCodeRValue (right, FALSE));
3320 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3324 return geniCodeAdd (geniCodeRValue (left, FALSE),
3325 geniCodeRValue (right, FALSE),lvl);
3327 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3330 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3331 geniCodeRValue (right, FALSE));
3334 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3335 geniCodeRValue (right, FALSE));
3337 return geniCodeCast (operandType (left),
3338 geniCodeRValue (right, FALSE), FALSE);
3344 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3348 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3349 setOperandType (op, UCHARTYPE);
3360 return geniCodeLogic (geniCodeRValue (left, FALSE),
3361 geniCodeRValue (right, FALSE),
3364 return geniCodeConditional (tree,lvl);
3367 return operandFromLit (getSize (tree->right->ftype));
3371 sym_link *rtype = operandType (right);
3372 sym_link *ltype = operandType (left);
3373 if (IS_PTR (rtype) && IS_ITEMP (right)
3374 && right->isaddr && compareType (rtype->next, ltype) == 1)
3375 right = geniCodeRValue (right, TRUE);
3377 right = geniCodeRValue (right, FALSE);
3379 geniCodeAssign (left, right, 0);
3384 geniCodeAssign (left,
3385 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3387 geniCodeRValue (right, FALSE),FALSE), 0);
3391 geniCodeAssign (left,
3392 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3394 geniCodeRValue (right, FALSE)), 0);
3397 geniCodeAssign (left,
3398 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3400 geniCodeRValue (right, FALSE)), 0);
3403 sym_link *rtype = operandType (right);
3404 sym_link *ltype = operandType (left);
3405 if (IS_PTR (rtype) && IS_ITEMP (right)
3406 && right->isaddr && compareType (rtype->next, ltype) == 1)
3407 right = geniCodeRValue (right, TRUE);
3409 right = geniCodeRValue (right, FALSE);
3412 return geniCodeAssign (left,
3413 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3419 sym_link *rtype = operandType (right);
3420 sym_link *ltype = operandType (left);
3421 if (IS_PTR (rtype) && IS_ITEMP (right)
3422 && right->isaddr && compareType (rtype->next, ltype) == 1)
3424 right = geniCodeRValue (right, TRUE);
3428 right = geniCodeRValue (right, FALSE);
3431 geniCodeAssign (left,
3432 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3438 geniCodeAssign (left,
3439 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3441 geniCodeRValue (right, FALSE)), 0);
3444 geniCodeAssign (left,
3445 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3447 geniCodeRValue (right, FALSE)), 0);
3450 geniCodeAssign (left,
3451 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3453 geniCodeRValue (right, FALSE),
3455 operandType (left)), 0);
3458 geniCodeAssign (left,
3459 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3461 geniCodeRValue (right, FALSE),
3463 operandType (left)), 0);
3466 geniCodeAssign (left,
3467 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3469 geniCodeRValue (right, FALSE),
3471 operandType (left)), 0);
3473 return geniCodeRValue (right, FALSE);
3476 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3479 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3480 return ast2iCode (tree->right,lvl+1);
3483 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3484 return ast2iCode (tree->right,lvl+1);
3487 geniCodeFunctionBody (tree,lvl);
3491 geniCodeReturn (right);
3495 geniCodeIfx (tree,lvl);
3499 geniCodeSwitch (tree,lvl);
3503 geniCodeInline (tree);
3507 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3514 /*-----------------------------------------------------------------*/
3515 /* reverseICChain - gets from the list and creates a linkedlist */
3516 /*-----------------------------------------------------------------*/
3523 while ((loop = getSet (&iCodeChain)))
3535 /*-----------------------------------------------------------------*/
3536 /* iCodeFromAst - given an ast will convert it to iCode */
3537 /*-----------------------------------------------------------------*/
3539 iCodeFromAst (ast * tree)
3541 returnLabel = newiTempLabel ("_return");
3542 entryLabel = newiTempLabel ("_entry");
3544 return reverseiCChain ();