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 */
43 /*-----------------------------------------------------------------*/
44 /* forward definition of some functions */
45 operand *geniCodeDivision (operand *, operand *);
46 operand *geniCodeAssign (operand *, operand *, int);
47 operand *geniCodeArray (operand *, operand *,int);
48 operand *geniCodeArray2Ptr (operand *);
49 operand *geniCodeRValue (operand *, bool);
50 operand *geniCodeDerefPtr (operand *,int);
51 int isLvaluereq(int lvl);
53 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
54 /* forward definition of ic print functions */
55 PRINTFUNC (picGetValueAtAddr);
56 PRINTFUNC (picSetValueAtAddr);
57 PRINTFUNC (picAddrOf);
58 PRINTFUNC (picGeneric);
59 PRINTFUNC (picGenericOne);
61 PRINTFUNC (picAssign);
65 PRINTFUNC (picJumpTable);
66 PRINTFUNC (picInline);
67 PRINTFUNC (picReceive);
69 iCodeTable codeTable[] =
71 {'!', "not", picGenericOne, NULL},
72 {'~', "~", picGenericOne, NULL},
73 {RRC, "rrc", picGenericOne, NULL},
74 {RLC, "rlc", picGenericOne, NULL},
75 {GETHBIT, "ghbit", picGenericOne, NULL},
76 {UNARYMINUS, "-", picGenericOne, NULL},
77 {IPUSH, "push", picGenericOne, NULL},
78 {IPOP, "pop", picGenericOne, NULL},
79 {CALL, "call", picGenericOne, NULL},
80 {PCALL, "pcall", picGenericOne, NULL},
81 {FUNCTION, "proc", picGenericOne, NULL},
82 {ENDFUNCTION, "eproc", picGenericOne, NULL},
83 {RETURN, "ret", picGenericOne, NULL},
84 {'+', "+", picGeneric, NULL},
85 {'-', "-", picGeneric, NULL},
86 {'*', "*", picGeneric, NULL},
87 {'/', "/", picGeneric, NULL},
88 {'%', "%", picGeneric, NULL},
89 {'>', ">", picGeneric, NULL},
90 {'<', "<", picGeneric, NULL},
91 {LE_OP, "<=", picGeneric, NULL},
92 {GE_OP, ">=", picGeneric, NULL},
93 {EQ_OP, "==", picGeneric, NULL},
94 {NE_OP, "!=", picGeneric, NULL},
95 {AND_OP, "&&", picGeneric, NULL},
96 {OR_OP, "||", picGeneric, NULL},
97 {'^', "^", picGeneric, NULL},
98 {'|', "|", picGeneric, NULL},
99 {BITWISEAND, "&", picGeneric, NULL},
100 {LEFT_OP, "<<", picGeneric, NULL},
101 {RIGHT_OP, ">>", picGeneric, NULL},
102 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
103 {ADDRESS_OF, "&", picAddrOf, NULL},
104 {CAST, "<>", picCast, NULL},
105 {'=', ":=", picAssign, NULL},
106 {LABEL, "", picLabel, NULL},
107 {GOTO, "", picGoto, NULL},
108 {JUMPTABLE, "jtab", picJumpTable, NULL},
109 {IFX, "if", picIfx, NULL},
110 {INLINEASM, "", picInline, NULL},
111 {RECEIVE, "recv", picReceive, NULL},
112 {SEND, "send", picGenericOne, NULL},
113 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
117 /*-----------------------------------------------------------------*/
118 /* operandName - returns the name of the operand */
119 /*-----------------------------------------------------------------*/
121 printOperand (operand * op, FILE * file)
138 opetype = getSpec (operandType (op));
139 if (SPEC_NOUN (opetype) == V_FLOAT)
140 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
142 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
143 printTypeChain (operandType (op), file);
150 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}" , */
151 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
153 OP_LIVEFROM (op), OP_LIVETO (op),
154 OP_SYMBOL (op)->stack,
155 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
159 printTypeChain (operandType (op), file);
160 if (SPIL_LOC (op) && IS_ITEMP (op))
161 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
166 /* if assigned to registers */
167 if (OP_SYMBOL (op)->nRegs)
169 if (OP_SYMBOL (op)->isspilt)
171 if (!OP_SYMBOL (op)->remat)
172 if (OP_SYMBOL (op)->usl.spillLoc)
173 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
174 OP_SYMBOL (op)->usl.spillLoc->rname :
175 OP_SYMBOL (op)->usl.spillLoc->name));
177 fprintf (file, "[err]");
179 fprintf (file, "[remat]");
185 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
186 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
191 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
192 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
193 /* if assigned to registers */
194 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
198 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
199 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
200 OP_SYMBOL (op)->regs[i]->name :
209 printTypeChain (op->operand.typeOperand, file);
215 fprintf (file, "\n");
220 /*-----------------------------------------------------------------*/
221 /* print functions */
222 /*-----------------------------------------------------------------*/
223 PRINTFUNC (picGetValueAtAddr)
226 printOperand (IC_RESULT (ic), of);
229 printOperand (IC_LEFT (ic), of);
235 PRINTFUNC (picSetValueAtAddr)
239 printOperand (IC_LEFT (ic), of);
240 fprintf (of, "] = ");
241 printOperand (IC_RIGHT (ic), of);
245 PRINTFUNC (picAddrOf)
248 printOperand (IC_RESULT (ic), of);
249 if (IS_ITEMP (IC_LEFT (ic)))
252 fprintf (of, " = &[");
253 printOperand (IC_LEFT (ic), of);
256 if (IS_ITEMP (IC_LEFT (ic)))
257 fprintf (of, " offsetAdd ");
260 printOperand (IC_RIGHT (ic), of);
262 if (IS_ITEMP (IC_LEFT (ic)))
268 PRINTFUNC (picJumpTable)
273 fprintf (of, "%s\t", s);
274 printOperand (IC_JTCOND (ic), of);
276 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
277 sym = setNextItem (IC_JTLABELS (ic)))
278 fprintf (of, "\t\t\t%s\n", sym->name);
281 PRINTFUNC (picGeneric)
284 printOperand (IC_RESULT (ic), of);
286 printOperand (IC_LEFT (ic), of);
287 fprintf (of, " %s ", s);
288 printOperand (IC_RIGHT (ic), of);
292 PRINTFUNC (picGenericOne)
297 printOperand (IC_RESULT (ic), of);
303 fprintf (of, "%s ", s);
304 printOperand (IC_LEFT (ic), of);
307 if (!IC_RESULT (ic) && !IC_LEFT (ic))
316 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
319 printOperand (IC_RIGHT (ic), of);
324 PRINTFUNC (picAssign)
328 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
331 printOperand (IC_RESULT (ic), of);
333 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
336 fprintf (of, " %s ", s);
337 printOperand (IC_RIGHT (ic), of);
344 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
350 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
357 printOperand (IC_COND (ic), of);
360 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
363 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
365 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
369 PRINTFUNC (picInline)
371 fprintf (of, "%s", IC_INLINE (ic));
374 PRINTFUNC (picReceive)
376 printOperand (IC_RESULT (ic), of);
377 fprintf (of, " = %s ", s);
378 printOperand (IC_LEFT (ic), of);
382 /*-----------------------------------------------------------------*/
383 /* piCode - prints one iCode */
384 /*-----------------------------------------------------------------*/
386 piCode (void *item, FILE * of)
394 icTab = getTableEntry (ic->op);
395 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
396 ic->filename, ic->lineno,
397 ic->seq, ic->key, ic->depth, ic->supportRtn);
398 icTab->iCodePrint (of, ic, icTab->printName);
404 printiCChain(ic,stdout);
406 /*-----------------------------------------------------------------*/
407 /* printiCChain - prints intermediate code for humans */
408 /*-----------------------------------------------------------------*/
410 printiCChain (iCode * icChain, FILE * of)
417 for (loop = icChain; loop; loop = loop->next)
419 if ((icTab = getTableEntry (loop->op)))
421 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
422 loop->filename, loop->lineno,
423 loop->seq, loop->key, loop->depth, loop->supportRtn);
425 icTab->iCodePrint (of, loop, icTab->printName);
431 /*-----------------------------------------------------------------*/
432 /* newOperand - allocate, init & return a new iCode */
433 /*-----------------------------------------------------------------*/
439 op = Safe_calloc (1, sizeof (operand));
445 /*-----------------------------------------------------------------*/
446 /* newiCode - create and return a new iCode entry initialised */
447 /*-----------------------------------------------------------------*/
449 newiCode (int op, operand * left, operand * right)
453 ic = Safe_calloc (1, sizeof (iCode));
456 ic->filename = filename;
458 ic->level = scopeLevel;
460 ic->key = iCodeKey++;
462 IC_RIGHT (ic) = right;
467 /*-----------------------------------------------------------------*/
468 /* newiCode for conditional statements */
469 /*-----------------------------------------------------------------*/
471 newiCodeCondition (operand * condition,
477 ic = newiCode (IFX, NULL, NULL);
478 IC_COND (ic) = condition;
479 IC_TRUE (ic) = trueLabel;
480 IC_FALSE (ic) = falseLabel;
484 /*-----------------------------------------------------------------*/
485 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
486 /*-----------------------------------------------------------------*/
488 newiCodeLabelGoto (int op, symbol * label)
492 ic = newiCode (op, NULL, NULL);
494 ic->argLabel.label = label;
496 IC_RIGHT (ic) = NULL;
497 IC_RESULT (ic) = NULL;
501 /*-----------------------------------------------------------------*/
502 /* newiTemp - allocate & return a newItemp Variable */
503 /*-----------------------------------------------------------------*/
510 sprintf (buffer, "%s", s);
512 sprintf (buffer, "iTemp%d", iTempNum++);
513 itmp = newSymbol (buffer, 1);
514 strcpy (itmp->rname, itmp->name);
520 /*-----------------------------------------------------------------*/
521 /* newiTempLabel - creates a temp variable label */
522 /*-----------------------------------------------------------------*/
524 newiTempLabel (char *s)
528 /* check if this alredy exists */
529 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
533 itmplbl = newSymbol (s, 1);
536 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
537 itmplbl = newSymbol (buffer, 1);
542 itmplbl->key = labelKey++;
543 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
547 /*-----------------------------------------------------------------*/
548 /* newiTempPreheaderLabel - creates a new preheader label */
549 /*-----------------------------------------------------------------*/
551 newiTempPreheaderLabel ()
555 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
556 itmplbl = newSymbol (buffer, 1);
560 itmplbl->key = labelKey++;
561 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
566 /*-----------------------------------------------------------------*/
567 /* initiCode - initialises some iCode related stuff */
568 /*-----------------------------------------------------------------*/
575 /*-----------------------------------------------------------------*/
576 /* copyiCode - make a copy of the iCode given */
577 /*-----------------------------------------------------------------*/
579 copyiCode (iCode * ic)
581 iCode *nic = newiCode (ic->op, NULL, NULL);
583 nic->lineno = ic->lineno;
584 nic->filename = ic->filename;
585 nic->block = ic->block;
586 nic->level = ic->level;
587 nic->parmBytes = ic->parmBytes;
589 /* deal with the special cases first */
593 IC_COND (nic) = operandFromOperand (IC_COND (ic));
594 IC_TRUE (nic) = IC_TRUE (ic);
595 IC_FALSE (nic) = IC_FALSE (ic);
599 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
600 IC_JTLABELS (nic) = IC_JTLABELS (ic);
605 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
606 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
607 IC_ARGS (nic) = IC_ARGS (ic);
611 IC_INLINE (nic) = IC_INLINE (ic);
615 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
619 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
620 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
621 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
627 /*-----------------------------------------------------------------*/
628 /* getTableEntry - gets the table entry for the given operator */
629 /*-----------------------------------------------------------------*/
631 getTableEntry (int oper)
635 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
636 if (oper == codeTable[i].icode)
637 return &codeTable[i];
642 /*-----------------------------------------------------------------*/
643 /* newiTempOperand - new intermediate temp operand */
644 /*-----------------------------------------------------------------*/
646 newiTempOperand (sym_link * type, char throwType)
649 operand *op = newOperand ();
653 itmp = newiTemp (NULL);
655 etype = getSpec (type);
657 if (IS_LITERAL (etype))
660 /* copy the type information */
662 itmp->etype = getSpec (itmp->type = (throwType ? type :
663 copyLinkChain (type)));
664 if (IS_LITERAL (itmp->etype))
666 SPEC_SCLS (itmp->etype) = S_REGISTER;
667 SPEC_OCLS (itmp->etype) = reg;
670 op->operand.symOperand = itmp;
671 op->key = itmp->key = ++operandKey;
675 /*-----------------------------------------------------------------*/
676 /* operandType - returns the type chain for an operand */
677 /*-----------------------------------------------------------------*/
679 operandType (operand * op)
681 /* depending on type of operand */
686 return op->operand.valOperand->type;
689 return op->operand.symOperand->type;
692 return op->operand.typeOperand;
694 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
695 " operand type not known ");
696 assert (0); /* should never come here */
697 /* Just to keep the compiler happy */
698 return (sym_link *) 0;
702 /*-----------------------------------------------------------------*/
703 /* isParamterToCall - will return 1 if op is a parameter to args */
704 /*-----------------------------------------------------------------*/
706 isParameterToCall (value * args, operand * op)
713 isSymbolEqual (op->operand.symOperand, tval->sym))
720 /*-----------------------------------------------------------------*/
721 /* isOperandGlobal - return 1 if operand is a global variable */
722 /*-----------------------------------------------------------------*/
724 isOperandGlobal (operand * op)
732 if (op->type == SYMBOL &&
733 (op->operand.symOperand->level == 0 ||
734 IS_STATIC (op->operand.symOperand->etype) ||
735 IS_EXTERN (op->operand.symOperand->etype))
742 /*-----------------------------------------------------------------*/
743 /* isOperandVolatile - return 1 if the operand is volatile */
744 /*-----------------------------------------------------------------*/
746 isOperandVolatile (operand * op, bool chkTemp)
751 if (IS_ITEMP (op) && !chkTemp)
754 opetype = getSpec (optype = operandType (op));
756 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
759 if (IS_VOLATILE (opetype))
764 /*-----------------------------------------------------------------*/
765 /* isOperandLiteral - returns 1 if an operand contains a literal */
766 /*-----------------------------------------------------------------*/
768 isOperandLiteral (operand * op)
775 opetype = getSpec (operandType (op));
777 if (IS_LITERAL (opetype))
782 /*-----------------------------------------------------------------*/
783 /* isOperandInFarSpace - will return true if operand is in farSpace */
784 /*-----------------------------------------------------------------*/
786 isOperandInFarSpace (operand * op)
796 if (!IS_TRUE_SYMOP (op))
799 etype = SPIL_LOC (op)->etype;
805 etype = getSpec (operandType (op));
807 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
810 /*-----------------------------------------------------------------*/
811 /* isOperandOnStack - will return true if operand is on stack */
812 /*-----------------------------------------------------------------*/
814 isOperandOnStack (operand * op)
824 etype = getSpec (operandType (op));
826 return ((IN_STACK (etype)) ? TRUE : FALSE);
829 /*-----------------------------------------------------------------*/
830 /* operandLitValue - literal value of an operand */
831 /*-----------------------------------------------------------------*/
833 operandLitValue (operand * op)
835 assert (isOperandLiteral (op));
837 return floatFromVal (op->operand.valOperand);
840 /*-----------------------------------------------------------------*/
841 /* operandOperation - perforoms operations on operands */
842 /*-----------------------------------------------------------------*/
844 operandOperation (operand * left, operand * right,
845 int op, sym_link * type)
847 sym_link *let , *ret=NULL;
848 operand *retval = (operand *) 0;
850 assert (isOperandLiteral (left));
851 let = getSpec(operandType(left));
853 assert (isOperandLiteral (right));
854 ret = getSpec(operandType(left));
860 retval = operandFromValue (valCastLiteral (type,
861 operandLitValue (left) +
862 operandLitValue (right)));
865 retval = operandFromValue (valCastLiteral (type,
866 operandLitValue (left) -
867 operandLitValue (right)));
870 retval = operandFromValue (valCastLiteral (type,
871 operandLitValue (left) *
872 operandLitValue (right)));
875 if ((unsigned long) operandLitValue (right) == 0)
877 werror (E_DIVIDE_BY_ZERO);
882 retval = operandFromValue (valCastLiteral (type,
883 operandLitValue (left) /
884 operandLitValue (right)));
887 if ((unsigned long) operandLitValue (right) == 0) {
888 werror (E_DIVIDE_BY_ZERO);
892 retval = operandFromLit ((SPEC_USIGN(let) ?
893 (unsigned long) operandLitValue (left) :
894 (long) operandLitValue (left)) %
896 (unsigned long) operandLitValue (right) :
897 (long) operandLitValue (right)));
901 retval = operandFromLit (((SPEC_USIGN(let) ?
902 (unsigned long) operandLitValue (left) :
903 (long) operandLitValue (left)) <<
905 (unsigned long) operandLitValue (right) :
906 (long) operandLitValue (right))));
909 retval = operandFromLit (((SPEC_USIGN(let) ?
910 (unsigned long) operandLitValue (left) :
911 (long) operandLitValue (left)) >>
913 (unsigned long) operandLitValue (right) :
914 (long) operandLitValue (right))));
917 retval = operandFromLit (operandLitValue (left) ==
918 operandLitValue (right));
921 retval = operandFromLit (operandLitValue (left) <
922 operandLitValue (right));
925 retval = operandFromLit (operandLitValue (left) <=
926 operandLitValue (right));
929 retval = operandFromLit (operandLitValue (left) !=
930 operandLitValue (right));
933 retval = operandFromLit (operandLitValue (left) >
934 operandLitValue (right));
937 retval = operandFromLit (operandLitValue (left) >=
938 operandLitValue (right));
941 retval = operandFromLit ((unsigned long) operandLitValue (left) &
942 (unsigned long) operandLitValue (right));
945 retval = operandFromLit ((unsigned long) operandLitValue (left) |
946 (unsigned long) operandLitValue (right));
949 retval = operandFromLit ((unsigned long) operandLitValue (left) ^
950 (unsigned long) operandLitValue (right));
953 retval = operandFromLit (operandLitValue (left) &&
954 operandLitValue (right));
957 retval = operandFromLit (operandLitValue (left) ||
958 operandLitValue (right));
962 long i = (long) operandLitValue (left);
964 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
970 long i = (long) operandLitValue (left);
972 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
978 retval = operandFromLit (-1 * operandLitValue (left));
982 retval = operandFromLit (~((long) operandLitValue (left)));
986 retval = operandFromLit (!operandLitValue (left));
990 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
991 " operandOperation invalid operator ");
999 /*-----------------------------------------------------------------*/
1000 /* isOperandEqual - compares two operand & return 1 if they r = */
1001 /*-----------------------------------------------------------------*/
1003 isOperandEqual (operand * left, operand * right)
1005 /* if the pointers are equal then they are equal */
1009 /* if either of them null then false */
1010 if (!left || !right)
1013 if (left->type != right->type)
1016 if (IS_SYMOP (left) && IS_SYMOP (right))
1017 return left->key == right->key;
1019 /* if types are the same */
1023 return isSymbolEqual (left->operand.symOperand,
1024 right->operand.symOperand);
1026 return (floatFromVal (left->operand.valOperand) ==
1027 floatFromVal (right->operand.valOperand));
1029 if (compareType (left->operand.typeOperand,
1030 right->operand.typeOperand) == 1)
1037 /*-----------------------------------------------------------------*/
1038 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1039 /*-----------------------------------------------------------------*/
1041 isiCodeEqual (iCode * left, iCode * right)
1043 /* if the same pointer */
1047 /* if either of them null */
1048 if (!left || !right)
1051 /* if operand are the same */
1052 if (left->op == right->op)
1055 /* compare all the elements depending on type */
1056 if (left->op != IFX)
1058 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1060 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1066 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1068 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1070 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1078 /*-----------------------------------------------------------------*/
1079 /* newiTempFromOp - create a temp Operand with same attributes */
1080 /*-----------------------------------------------------------------*/
1082 newiTempFromOp (operand * op)
1092 nop = newiTempOperand (operandType (op), TRUE);
1093 nop->isaddr = op->isaddr;
1094 nop->isvolatile = op->isvolatile;
1095 nop->isGlobal = op->isGlobal;
1096 nop->isLiteral = op->isLiteral;
1097 nop->usesDefs = op->usesDefs;
1098 nop->isParm = op->isParm;
1102 /*-----------------------------------------------------------------*/
1103 /* operand from operand - creates an operand holder for the type */
1104 /*-----------------------------------------------------------------*/
1106 operandFromOperand (operand * op)
1112 nop = newOperand ();
1113 nop->type = op->type;
1114 nop->isaddr = op->isaddr;
1116 nop->isvolatile = op->isvolatile;
1117 nop->isGlobal = op->isGlobal;
1118 nop->isLiteral = op->isLiteral;
1119 nop->usesDefs = op->usesDefs;
1120 nop->isParm = op->isParm;
1125 nop->operand.symOperand = op->operand.symOperand;
1128 nop->operand.valOperand = op->operand.valOperand;
1131 nop->operand.typeOperand = op->operand.typeOperand;
1138 /*-----------------------------------------------------------------*/
1139 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1140 /*-----------------------------------------------------------------*/
1142 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1144 operand *nop = operandFromOperand (op);
1146 if (nop->type == SYMBOL)
1148 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1149 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1155 /*-----------------------------------------------------------------*/
1156 /* operandFromSymbol - creates an operand from a symbol */
1157 /*-----------------------------------------------------------------*/
1159 operandFromSymbol (symbol * sym)
1164 /* if the symbol's type is a literal */
1165 /* then it is an enumerator type */
1166 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1167 return operandFromValue (valFromType (sym->etype));
1170 sym->key = ++operandKey;
1172 /* if this an implicit variable, means struct/union */
1173 /* member so just return it */
1174 if (sym->implicit || IS_FUNC (sym->type))
1178 op->operand.symOperand = sym;
1180 op->isvolatile = isOperandVolatile (op, TRUE);
1181 op->isGlobal = isOperandGlobal (op);
1185 /* under the following conditions create a
1186 register equivalent for a local symbol */
1187 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1188 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1189 /* (!TARGET_IS_DS390)) && */
1190 (!(options.model == MODEL_FLAT24)) ) &&
1191 options.stackAuto == 0)
1194 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1195 !IS_FUNC (sym->type) && /* not a function */
1196 !sym->_isparm && /* not a parameter */
1197 sym->level && /* is a local variable */
1198 !sym->addrtaken && /* whose address has not been taken */
1199 !sym->reqv && /* does not already have a register euivalence */
1200 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1201 !IS_STATIC (sym->etype) && /* and not declared static */
1202 !sym->islbl && /* not a label */
1203 ok && /* farspace check */
1204 !IS_BITVAR (sym->etype) /* not a bit variable */
1208 /* we will use it after all optimizations
1209 and before liveRange calculation */
1210 sym->reqv = newiTempOperand (sym->type, 0);
1211 sym->reqv->key = sym->key;
1212 OP_SYMBOL (sym->reqv)->key = sym->key;
1213 OP_SYMBOL (sym->reqv)->isreqv = 1;
1214 OP_SYMBOL (sym->reqv)->islocal = 1;
1215 SPIL_LOC (sym->reqv) = sym;
1218 if (!IS_AGGREGATE (sym->type))
1222 op->operand.symOperand = sym;
1225 op->isvolatile = isOperandVolatile (op, TRUE);
1226 op->isGlobal = isOperandGlobal (op);
1227 op->isPtr = IS_PTR (operandType (op));
1228 op->isParm = sym->_isparm;
1233 /* itemp = &[_symbol] */
1235 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1236 IC_LEFT (ic)->type = SYMBOL;
1237 IC_LEFT (ic)->operand.symOperand = sym;
1238 IC_LEFT (ic)->key = sym->key;
1239 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1240 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1241 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1244 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1245 if (IS_ARRAY (sym->type))
1247 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1248 IC_RESULT (ic)->isaddr = 0;
1251 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1253 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1257 return IC_RESULT (ic);
1260 /*-----------------------------------------------------------------*/
1261 /* operandFromValue - creates an operand from value */
1262 /*-----------------------------------------------------------------*/
1264 operandFromValue (value * val)
1268 /* if this is a symbol then do the symbol thing */
1270 return operandFromSymbol (val->sym);
1272 /* this is not a symbol */
1275 op->operand.valOperand = val;
1276 op->isLiteral = isOperandLiteral (op);
1280 /*-----------------------------------------------------------------*/
1281 /* operandFromLink - operand from typeChain */
1282 /*-----------------------------------------------------------------*/
1284 operandFromLink (sym_link * type)
1288 /* operand from sym_link */
1294 op->operand.typeOperand = copyLinkChain (type);
1298 /*-----------------------------------------------------------------*/
1299 /* operandFromLit - makes an operand from a literal value */
1300 /*-----------------------------------------------------------------*/
1302 operandFromLit (double i)
1304 return operandFromValue (valueFromLit (i));
1307 /*-----------------------------------------------------------------*/
1308 /* operandFromAst - creates an operand from an ast */
1309 /*-----------------------------------------------------------------*/
1311 operandFromAst (ast * tree,int lvl)
1317 /* depending on type do */
1321 return ast2iCode (tree,lvl+1);
1325 return operandFromValue (tree->opval.val);
1329 return operandFromLink (tree->opval.lnk);
1333 /* Just to keep the comiler happy */
1334 return (operand *) 0;
1337 /*-----------------------------------------------------------------*/
1338 /* setOperandType - sets the operand's type to the given type */
1339 /*-----------------------------------------------------------------*/
1341 setOperandType (operand * op, sym_link * type)
1343 /* depending on the type of operand */
1348 op->operand.valOperand->etype =
1349 getSpec (op->operand.valOperand->type =
1350 copyLinkChain (type));
1354 if (op->operand.symOperand->isitmp)
1355 op->operand.symOperand->etype =
1356 getSpec (op->operand.symOperand->type =
1357 copyLinkChain (type));
1359 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1360 "attempt to modify type of source");
1364 op->operand.typeOperand = copyLinkChain (type);
1369 /*-----------------------------------------------------------------*/
1370 /* Get size in byte of ptr need to access an array */
1371 /*-----------------------------------------------------------------*/
1373 getArraySizePtr (operand * op)
1375 sym_link *ltype = operandType(op);
1379 int size = getSize(ltype);
1380 return(IS_GENPTR(ltype)?(size-1):size);
1385 sym_link *letype = getSpec(ltype);
1386 switch (PTR_TYPE (SPEC_OCLS (letype)))
1398 return (GPTRSIZE-1);
1407 /*-----------------------------------------------------------------*/
1408 /* perform "usual unary conversions" */
1409 /*-----------------------------------------------------------------*/
1411 usualUnaryConversions (operand * op)
1413 if (IS_INTEGRAL (operandType (op)))
1415 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1418 return geniCodeCast (INTTYPE, op, TRUE);
1424 /*-----------------------------------------------------------------*/
1425 /* perform "usual binary conversions" */
1426 /*-----------------------------------------------------------------*/
1428 usualBinaryConversions (operand ** op1, operand ** op2)
1431 sym_link *rtype = operandType (*op2);
1432 sym_link *ltype = operandType (*op1);
1434 ctype = computeType (ltype, rtype);
1435 *op1 = geniCodeCast (ctype, *op1, TRUE);
1436 *op2 = geniCodeCast (ctype, *op2, TRUE);
1441 /*-----------------------------------------------------------------*/
1442 /* geniCodeValueAtAddress - generate intermeditate code for value */
1444 /*-----------------------------------------------------------------*/
1446 geniCodeRValue (operand * op, bool force)
1449 sym_link *type = operandType (op);
1450 sym_link *etype = getSpec (type);
1452 /* if this is an array & already */
1453 /* an address then return this */
1454 if (IS_AGGREGATE (type) ||
1455 (IS_PTR (type) && !force && !op->isaddr))
1456 return operandFromOperand (op);
1458 /* if this is not an address then must be */
1459 /* rvalue already so return this one */
1463 /* if this is not a temp symbol then */
1464 if (!IS_ITEMP (op) &&
1466 !IN_FARSPACE (SPEC_OCLS (etype)))
1468 op = operandFromOperand (op);
1473 if (IS_SPEC (type) &&
1474 IS_TRUE_SYMOP (op) &&
1475 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1476 /* TARGET_IS_DS390)) */
1477 (options.model == MODEL_FLAT24) ))
1479 op = operandFromOperand (op);
1484 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1485 if (IS_PTR (type) && op->isaddr && force)
1488 type = copyLinkChain (type);
1490 IC_RESULT (ic) = newiTempOperand (type, 1);
1491 IC_RESULT (ic)->isaddr = 0;
1493 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1495 /* if the right is a symbol */
1496 if (op->type == SYMBOL)
1497 IC_RESULT (ic)->operand.symOperand->args =
1498 op->operand.symOperand->args;
1501 return IC_RESULT (ic);
1504 /*-----------------------------------------------------------------*/
1505 /* geniCodeCast - changes the value from one type to another */
1506 /*-----------------------------------------------------------------*/
1508 geniCodeCast (sym_link * type, operand * op, bool implicit)
1512 sym_link *opetype = getSpec (optype = operandType (op));
1515 /* one of them has size zero then error */
1516 if (IS_VOID (optype))
1518 werror (E_CAST_ZERO);
1522 /* if the operand is already the desired type then do nothing */
1523 if (compareType (type, optype) == 1)
1526 /* if this is a literal then just change the type & return */
1527 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1528 return operandFromValue (valCastLiteral (type,
1529 operandLitValue (op)));
1531 /* if casting to some pointer type &&
1532 the destination is not a generic pointer
1533 then give a warning : (only for implicit casts) */
1534 if (IS_PTR (optype) && implicit &&
1535 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1538 werror (E_INCOMPAT_CAST);
1539 fprintf (stderr, "from type '");
1540 printTypeChain (optype, stderr);
1541 fprintf (stderr, "' to type '");
1542 printTypeChain (type, stderr);
1543 fprintf (stderr, "'\n");
1546 /* if they are the same size create an assignment */
1547 if (getSize (type) == getSize (optype) &&
1548 !IS_BITFIELD (type) &&
1550 !IS_FLOAT (optype) &&
1551 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1552 (!IS_SPEC (type) && !IS_SPEC (optype))))
1555 ic = newiCode ('=', NULL, op);
1556 IC_RESULT (ic) = newiTempOperand (type, 0);
1557 SPIL_LOC (IC_RESULT (ic)) =
1558 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1559 IC_RESULT (ic)->isaddr = 0;
1563 ic = newiCode (CAST, operandFromLink (type),
1564 geniCodeRValue (op, FALSE));
1566 IC_RESULT (ic) = newiTempOperand (type, 0);
1569 /* preserve the storage class & output class */
1570 /* of the original variable */
1571 restype = getSpec (operandType (IC_RESULT (ic)));
1572 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1573 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1576 return IC_RESULT (ic);
1579 /*-----------------------------------------------------------------*/
1580 /* geniCodeLabel - will create a Label */
1581 /*-----------------------------------------------------------------*/
1583 geniCodeLabel (symbol * label)
1587 ic = newiCodeLabelGoto (LABEL, label);
1591 /*-----------------------------------------------------------------*/
1592 /* geniCodeGoto - will create a Goto */
1593 /*-----------------------------------------------------------------*/
1595 geniCodeGoto (symbol * label)
1599 ic = newiCodeLabelGoto (GOTO, label);
1603 /*-----------------------------------------------------------------*/
1604 /* geniCodeMultiply - gen intermediate code for multiplication */
1605 /*-----------------------------------------------------------------*/
1607 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1614 /* if they are both literal then we know the result */
1615 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1616 return operandFromValue (valMult (left->operand.valOperand,
1617 right->operand.valOperand));
1619 if (IS_LITERAL(retype)) {
1620 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1623 resType = usualBinaryConversions (&left, &right);
1625 rtype = operandType (right);
1626 retype = getSpec (rtype);
1627 ltype = operandType (left);
1628 letype = getSpec (ltype);
1632 SPEC_NOUN(getSpec(resType))=V_INT;
1635 /* if the right is a literal & power of 2 */
1636 /* then make it a left shift */
1637 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1638 efficient in most cases than 2 bytes result = 2 bytes << literal
1639 if port has 1 byte muldiv */
1640 if (p2 && !IS_FLOAT (letype) &&
1641 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1642 (port->support.muldiv == 1)))
1644 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1646 /* LEFT_OP need same size for left and result, */
1647 left = geniCodeCast (resType, left, TRUE);
1648 ltype = operandType (left);
1650 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1654 ic = newiCode ('*', left, right); /* normal multiplication */
1655 /* if the size left or right > 1 then support routine */
1656 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1660 IC_RESULT (ic) = newiTempOperand (resType, 1);
1663 return IC_RESULT (ic);
1666 /*-----------------------------------------------------------------*/
1667 /* geniCodeDivision - gen intermediate code for division */
1668 /*-----------------------------------------------------------------*/
1670 geniCodeDivision (operand * left, operand * right)
1675 sym_link *rtype = operandType (right);
1676 sym_link *retype = getSpec (rtype);
1677 sym_link *ltype = operandType (left);
1678 sym_link *letype = getSpec (ltype);
1680 resType = usualBinaryConversions (&left, &right);
1682 /* if the right is a literal & power of 2 */
1683 /* then make it a right shift */
1684 if (IS_LITERAL (retype) &&
1685 !IS_FLOAT (letype) &&
1686 (p2 = powof2 ((unsigned long)
1687 floatFromVal (right->operand.valOperand)))) {
1688 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1692 ic = newiCode ('/', left, right); /* normal division */
1693 /* if the size left or right > 1 then support routine */
1694 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1697 IC_RESULT (ic) = newiTempOperand (resType, 0);
1700 return IC_RESULT (ic);
1702 /*-----------------------------------------------------------------*/
1703 /* geniCodeModulus - gen intermediate code for modulus */
1704 /*-----------------------------------------------------------------*/
1706 geniCodeModulus (operand * left, operand * right)
1712 /* if they are both literal then we know the result */
1713 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1714 return operandFromValue (valMod (left->operand.valOperand,
1715 right->operand.valOperand));
1717 resType = usualBinaryConversions (&left, &right);
1719 /* now they are the same size */
1720 ic = newiCode ('%', left, right);
1722 /* if the size left or right > 1 then support routine */
1723 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1725 IC_RESULT (ic) = newiTempOperand (resType, 0);
1728 return IC_RESULT (ic);
1731 /*-----------------------------------------------------------------*/
1732 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1733 /*-----------------------------------------------------------------*/
1735 geniCodePtrPtrSubtract (operand * left, operand * right)
1741 /* if they are both literals then */
1742 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1744 result = operandFromValue (valMinus (left->operand.valOperand,
1745 right->operand.valOperand));
1749 ic = newiCode ('-', left, right);
1751 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1755 return geniCodeDivision (result,
1756 operandFromLit (getSize (ltype->next)));
1759 /*-----------------------------------------------------------------*/
1760 /* geniCodeSubtract - generates code for subtraction */
1761 /*-----------------------------------------------------------------*/
1763 geniCodeSubtract (operand * left, operand * right)
1770 /* if they both pointers then */
1771 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1772 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1773 return geniCodePtrPtrSubtract (left, right);
1775 /* if they are both literal then we know the result */
1776 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1777 && left->isLiteral && right->isLiteral)
1778 return operandFromValue (valMinus (left->operand.valOperand,
1779 right->operand.valOperand));
1781 /* if left is an array or pointer */
1782 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1784 isarray = left->isaddr;
1785 right = geniCodeMultiply (right,
1786 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1787 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1790 { /* make them the same size */
1791 resType = usualBinaryConversions (&left, &right);
1794 ic = newiCode ('-', left, right);
1796 IC_RESULT (ic) = newiTempOperand (resType, 1);
1797 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1799 /* if left or right is a float */
1800 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1804 return IC_RESULT (ic);
1807 /*-----------------------------------------------------------------*/
1808 /* geniCodeAdd - generates iCode for addition */
1809 /*-----------------------------------------------------------------*/
1811 geniCodeAdd (operand * left, operand * right,int lvl)
1819 /* if left is an array then array access */
1820 if (IS_ARRAY (ltype))
1821 return geniCodeArray (left, right,lvl);
1823 /* if the right side is LITERAL zero */
1824 /* return the left side */
1825 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1828 /* if left is literal zero return right */
1829 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1832 /* if left is an array or pointer then size */
1835 isarray = left->isaddr;
1836 // there is no need to multiply with 1
1837 if (getSize(ltype->next)!=1) {
1838 size = operandFromLit (getSize (ltype->next));
1839 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1841 resType = copyLinkChain (ltype);
1844 { /* make them the same size */
1845 resType = usualBinaryConversions (&left, &right);
1848 /* if they are both literals then we know */
1849 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1850 && left->isLiteral && right->isLiteral)
1851 return operandFromValue (valPlus (valFromType (letype),
1852 valFromType (retype)));
1854 ic = newiCode ('+', left, right);
1856 IC_RESULT (ic) = newiTempOperand (resType, 1);
1857 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1859 /* if left or right is a float then support
1861 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1866 return IC_RESULT (ic);
1870 /*-----------------------------------------------------------------*/
1871 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1872 /*-----------------------------------------------------------------*/
1874 aggrToPtr (sym_link * type, bool force)
1880 if (IS_PTR (type) && !force)
1883 etype = getSpec (type);
1887 /* if the output class is generic */
1888 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1889 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1891 /* if the variable was declared a constant */
1892 /* then the pointer points to a constant */
1893 if (IS_CONSTANT (etype))
1894 DCL_PTR_CONST (ptype) = 1;
1896 /* the variable was volatile then pointer to volatile */
1897 if (IS_VOLATILE (etype))
1898 DCL_PTR_VOLATILE (ptype) = 1;
1902 /*-----------------------------------------------------------------*/
1903 /* geniCodeArray2Ptr - array to pointer */
1904 /*-----------------------------------------------------------------*/
1906 geniCodeArray2Ptr (operand * op)
1908 sym_link *optype = operandType (op);
1909 sym_link *opetype = getSpec (optype);
1911 /* set the pointer depending on the storage class */
1912 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1913 DCL_PTR_CONST (optype) = port->mem.code_ro;
1916 /* if the variable was declared a constant */
1917 /* then the pointer points to a constant */
1918 if (IS_CONSTANT (opetype))
1919 DCL_PTR_CONST (optype) = 1;
1921 /* the variable was volatile then pointer to volatile */
1922 if (IS_VOLATILE (opetype))
1923 DCL_PTR_VOLATILE (optype) = 1;
1929 /*-----------------------------------------------------------------*/
1930 /* geniCodeArray - array access */
1931 /*-----------------------------------------------------------------*/
1933 geniCodeArray (operand * left, operand * right,int lvl)
1936 sym_link *ltype = operandType (left);
1940 if (IS_PTR (ltype->next) && left->isaddr)
1942 left = geniCodeRValue (left, FALSE);
1944 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
1947 right = geniCodeMultiply (right,
1948 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1950 /* we can check for limits here */
1951 if (isOperandLiteral (right) &&
1954 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
1956 werror (E_ARRAY_BOUND);
1957 right = operandFromLit (0);
1960 ic = newiCode ('+', left, right);
1962 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
1963 !IS_AGGREGATE (ltype->next) &&
1964 !IS_PTR (ltype->next))
1965 ? ltype : ltype->next), 0);
1967 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
1969 return IC_RESULT (ic);
1972 /*-----------------------------------------------------------------*/
1973 /* geniCodeStruct - generates intermediate code for structres */
1974 /*-----------------------------------------------------------------*/
1976 geniCodeStruct (operand * left, operand * right, bool islval)
1979 sym_link *type = operandType (left);
1980 sym_link *etype = getSpec (type);
1982 symbol *element = getStructElement (SPEC_STRUCT (etype),
1983 right->operand.symOperand);
1985 /* add the offset */
1986 ic = newiCode ('+', left, operandFromLit (element->offset));
1988 IC_RESULT (ic) = newiTempOperand (element->type, 0);
1990 /* preserve the storage & output class of the struct */
1991 /* as well as the volatile attribute */
1992 retype = getSpec (operandType (IC_RESULT (ic)));
1993 SPEC_SCLS (retype) = SPEC_SCLS (etype);
1994 SPEC_OCLS (retype) = SPEC_OCLS (etype);
1995 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
1997 if (IS_PTR (element->type))
1998 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2000 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2004 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2007 /*-----------------------------------------------------------------*/
2008 /* geniCodePostInc - generate int code for Post increment */
2009 /*-----------------------------------------------------------------*/
2011 geniCodePostInc (operand * op)
2015 sym_link *optype = operandType (op);
2017 operand *rv = (IS_ITEMP (op) ?
2018 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2020 sym_link *rvtype = operandType (rv);
2023 /* if this is not an address we have trouble */
2026 werror (E_LVALUE_REQUIRED, "++");
2030 rOp = newiTempOperand (rvtype, 0);
2031 OP_SYMBOL(rOp)->noSpilLoc = 1;
2034 OP_SYMBOL(rv)->noSpilLoc = 1;
2036 geniCodeAssign (rOp, rv, 0);
2038 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2039 if (IS_FLOAT (rvtype))
2040 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2042 ic = newiCode ('+', rv, operandFromLit (size));
2044 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2047 geniCodeAssign (op, result, 0);
2053 /*-----------------------------------------------------------------*/
2054 /* geniCodePreInc - generate code for preIncrement */
2055 /*-----------------------------------------------------------------*/
2057 geniCodePreInc (operand * op)
2060 sym_link *optype = operandType (op);
2061 operand *rop = (IS_ITEMP (op) ?
2062 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2064 sym_link *roptype = operandType (rop);
2070 werror (E_LVALUE_REQUIRED, "++");
2075 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2076 if (IS_FLOAT (roptype))
2077 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2079 ic = newiCode ('+', rop, operandFromLit (size));
2080 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2084 return geniCodeAssign (op, result, 0);
2087 /*-----------------------------------------------------------------*/
2088 /* geniCodePostDec - generates code for Post decrement */
2089 /*-----------------------------------------------------------------*/
2091 geniCodePostDec (operand * op)
2095 sym_link *optype = operandType (op);
2097 operand *rv = (IS_ITEMP (op) ?
2098 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2100 sym_link *rvtype = operandType (rv);
2103 /* if this is not an address we have trouble */
2106 werror (E_LVALUE_REQUIRED, "++");
2110 rOp = newiTempOperand (rvtype, 0);
2111 OP_SYMBOL(rOp)->noSpilLoc = 1;
2114 OP_SYMBOL(rv)->noSpilLoc = 1;
2116 geniCodeAssign (rOp, rv, 0);
2118 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2119 if (IS_FLOAT (rvtype))
2120 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2122 ic = newiCode ('-', rv, operandFromLit (size));
2124 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2127 geniCodeAssign (op, result, 0);
2133 /*-----------------------------------------------------------------*/
2134 /* geniCodePreDec - generate code for pre decrement */
2135 /*-----------------------------------------------------------------*/
2137 geniCodePreDec (operand * op)
2140 sym_link *optype = operandType (op);
2141 operand *rop = (IS_ITEMP (op) ?
2142 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2144 sym_link *roptype = operandType (rop);
2150 werror (E_LVALUE_REQUIRED, "++");
2155 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2156 if (IS_FLOAT (roptype))
2157 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2159 ic = newiCode ('-', rop, operandFromLit (size));
2160 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2164 return geniCodeAssign (op, result, 0);
2168 /*-----------------------------------------------------------------*/
2169 /* geniCodeBitwise - gen int code for bitWise operators */
2170 /*-----------------------------------------------------------------*/
2172 geniCodeBitwise (operand * left, operand * right,
2173 int oper, sym_link * resType)
2177 left = geniCodeCast (resType, left, TRUE);
2178 right = geniCodeCast (resType, right, TRUE);
2180 ic = newiCode (oper, left, right);
2181 IC_RESULT (ic) = newiTempOperand (resType, 0);
2184 return IC_RESULT (ic);
2187 /*-----------------------------------------------------------------*/
2188 /* geniCodeAddressOf - gens icode for '&' address of operator */
2189 /*-----------------------------------------------------------------*/
2191 geniCodeAddressOf (operand * op)
2195 sym_link *optype = operandType (op);
2196 sym_link *opetype = getSpec (optype);
2198 /* lvalue check already done in decorateType */
2199 /* this must be a lvalue */
2200 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2201 /* werror (E_LVALUE_REQUIRED,"&"); */
2206 p->class = DECLARATOR;
2208 /* set the pointer depending on the storage class */
2209 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2210 DCL_PTR_CONST (p) = port->mem.code_ro;
2212 /* make sure we preserve the const & volatile */
2213 if (IS_CONSTANT (opetype))
2214 DCL_PTR_CONST (p) = 1;
2216 if (IS_VOLATILE (opetype))
2217 DCL_PTR_VOLATILE (p) = 1;
2219 p->next = copyLinkChain (optype);
2221 /* if already a temp */
2224 setOperandType (op, p);
2229 /* other wise make this of the type coming in */
2230 ic = newiCode (ADDRESS_OF, op, NULL);
2231 IC_RESULT (ic) = newiTempOperand (p, 1);
2232 IC_RESULT (ic)->isaddr = 0;
2234 return IC_RESULT (ic);
2236 /*-----------------------------------------------------------------*/
2237 /* setOClass - sets the output class depending on the pointer type */
2238 /*-----------------------------------------------------------------*/
2240 setOClass (sym_link * ptr, sym_link * spec)
2242 switch (DCL_TYPE (ptr))
2245 SPEC_OCLS (spec) = data;
2249 SPEC_OCLS (spec) = generic;
2253 SPEC_OCLS (spec) = xdata;
2257 SPEC_OCLS (spec) = code;
2261 SPEC_OCLS (spec) = idata;
2265 SPEC_OCLS (spec) = xstack;
2269 SPEC_OCLS (spec) = eeprom;
2278 /*-----------------------------------------------------------------*/
2279 /* geniCodeDerefPtr - dereference pointer with '*' */
2280 /*-----------------------------------------------------------------*/
2282 geniCodeDerefPtr (operand * op,int lvl)
2284 sym_link *rtype, *retype;
2285 sym_link *optype = operandType (op);
2287 /* if this is a pointer then generate the rvalue */
2288 if (IS_PTR (optype))
2290 if (IS_TRUE_SYMOP (op))
2293 op = geniCodeRValue (op, TRUE);
2296 op = geniCodeRValue (op, TRUE);
2299 /* now get rid of the pointer part */
2300 if (isLvaluereq(lvl) && IS_ITEMP (op))
2302 retype = getSpec (rtype = copyLinkChain (optype));
2306 retype = getSpec (rtype = copyLinkChain (optype->next));
2309 /* if this is a pointer then outputclass needs 2b updated */
2310 if (IS_PTR (optype))
2311 setOClass (optype, retype);
2313 op->isGptr = IS_GENPTR (optype);
2315 /* if the pointer was declared as a constant */
2316 /* then we cannot allow assignment to the derefed */
2317 if (IS_PTR_CONST (optype))
2318 SPEC_CONST (retype) = 1;
2320 op->isaddr = (IS_PTR (rtype) ||
2321 IS_STRUCT (rtype) ||
2326 if (!isLvaluereq(lvl))
2327 op = geniCodeRValue (op, TRUE);
2329 setOperandType (op, rtype);
2334 /*-----------------------------------------------------------------*/
2335 /* geniCodeUnaryMinus - does a unary minus of the operand */
2336 /*-----------------------------------------------------------------*/
2338 geniCodeUnaryMinus (operand * op)
2341 sym_link *optype = operandType (op);
2343 if (IS_LITERAL (optype))
2344 return operandFromLit (-floatFromVal (op->operand.valOperand));
2346 ic = newiCode (UNARYMINUS, op, NULL);
2347 IC_RESULT (ic) = newiTempOperand (optype, 0);
2349 return IC_RESULT (ic);
2352 /*-----------------------------------------------------------------*/
2353 /* geniCodeLeftShift - gen i code for left shift */
2354 /*-----------------------------------------------------------------*/
2356 geniCodeLeftShift (operand * left, operand * right)
2360 ic = newiCode (LEFT_OP, left, right);
2361 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2363 return IC_RESULT (ic);
2366 /*-----------------------------------------------------------------*/
2367 /* geniCodeRightShift - gen i code for right shift */
2368 /*-----------------------------------------------------------------*/
2370 geniCodeRightShift (operand * left, operand * right)
2374 ic = newiCode (RIGHT_OP, left, right);
2375 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2377 return IC_RESULT (ic);
2380 #if defined(__BORLANDC__) || defined(_MSC_VER)
2381 #define LONG_LONG __int64
2383 #define LONG_LONG long long
2386 /*-----------------------------------------------------------------*/
2387 /* geniCodeLogic- logic code */
2388 /*-----------------------------------------------------------------*/
2390 geniCodeLogic (operand * left, operand * right, int op)
2394 sym_link *rtype = operandType (right);
2395 sym_link *ltype = operandType (left);
2397 /* left is integral type and right is literal then
2398 check if the literal value is within bounds */
2399 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2401 int nbits = bitsForType (ltype);
2402 long v = (long) operandLitValue (right);
2404 if (v >= ((LONG_LONG) 1 << nbits) && v > 0)
2405 werror (W_CONST_RANGE, " compare operation ");
2408 ctype = usualBinaryConversions (&left, &right);
2410 ic = newiCode (op, left, right);
2411 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2413 /* if comparing float
2414 and not a '==' || '!=' || '&&' || '||' (these
2416 if (IS_FLOAT(ctype) &&
2424 return IC_RESULT (ic);
2427 /*-----------------------------------------------------------------*/
2428 /* geniCodeUnary - for a a generic unary operation */
2429 /*-----------------------------------------------------------------*/
2431 geniCodeUnary (operand * op, int oper)
2433 iCode *ic = newiCode (oper, op, NULL);
2435 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2437 return IC_RESULT (ic);
2440 /*-----------------------------------------------------------------*/
2441 /* geniCodeConditional - geniCode for '?' ':' operation */
2442 /*-----------------------------------------------------------------*/
2444 geniCodeConditional (ast * tree,int lvl)
2447 symbol *falseLabel = newiTempLabel (NULL);
2448 symbol *exitLabel = newiTempLabel (NULL);
2449 operand *cond = ast2iCode (tree->left,lvl+1);
2450 operand *true, *false, *result;
2452 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2456 true = ast2iCode (tree->right->left,lvl+1);
2458 /* move the value to a new Operand */
2459 result = newiTempOperand (operandType (true), 0);
2460 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2462 /* generate an unconditional goto */
2463 geniCodeGoto (exitLabel);
2465 /* now for the right side */
2466 geniCodeLabel (falseLabel);
2468 false = ast2iCode (tree->right->right,lvl+1);
2469 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2471 /* create the exit label */
2472 geniCodeLabel (exitLabel);
2477 /*-----------------------------------------------------------------*/
2478 /* geniCodeAssign - generate code for assignment */
2479 /*-----------------------------------------------------------------*/
2481 geniCodeAssign (operand * left, operand * right, int nosupdate)
2484 sym_link *ltype = operandType (left);
2485 sym_link *rtype = operandType (right);
2487 if (!left->isaddr && !IS_ITEMP (left))
2489 werror (E_LVALUE_REQUIRED, "assignment");
2493 /* left is integral type and right is literal then
2494 check if the literal value is within bounds */
2495 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2497 int nbits = bitsForType (ltype);
2498 long v = (long) operandLitValue (right);
2500 if (v >= ((LONG_LONG) 1 << nbits) && v > 0)
2501 werror (W_CONST_RANGE, " = operation");
2504 /* if the left & right type don't exactly match */
2505 /* if pointer set then make sure the check is
2506 done with the type & not the pointer */
2507 /* then cast rights type to left */
2509 /* first check the type for pointer assignement */
2510 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2511 compareType (ltype, rtype) < 0)
2513 if (compareType (ltype->next, rtype) < 0)
2514 right = geniCodeCast (ltype->next, right, TRUE);
2516 else if (compareType (ltype, rtype) < 0)
2517 right = geniCodeCast (ltype, right, TRUE);
2519 /* if left is a true symbol & ! volatile
2520 create an assignment to temporary for
2521 the right & then assign this temporary
2522 to the symbol this is SSA . isn't it simple
2523 and folks have published mountains of paper on it */
2524 if (IS_TRUE_SYMOP (left) &&
2525 !isOperandVolatile (left, FALSE) &&
2526 isOperandGlobal (left))
2530 if (IS_TRUE_SYMOP (right))
2531 sym = OP_SYMBOL (right);
2532 ic = newiCode ('=', NULL, right);
2533 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2534 SPIL_LOC (right) = sym;
2538 ic = newiCode ('=', NULL, right);
2539 IC_RESULT (ic) = left;
2542 /* if left isgptr flag is set then support
2543 routine will be required */
2547 ic->nosupdate = nosupdate;
2551 /*-----------------------------------------------------------------*/
2552 /* geniCodeSEParms - generate code for side effecting fcalls */
2553 /*-----------------------------------------------------------------*/
2555 geniCodeSEParms (ast * parms,int lvl)
2560 if (parms->type == EX_OP && parms->opval.op == PARAM)
2562 geniCodeSEParms (parms->left,lvl);
2563 geniCodeSEParms (parms->right,lvl);
2567 /* hack don't like this but too lazy to think of
2569 if (IS_ADDRESS_OF_OP (parms))
2570 parms->left->lvalue = 1;
2572 if (IS_CAST_OP (parms) &&
2573 IS_PTR (parms->ftype) &&
2574 IS_ADDRESS_OF_OP (parms->right))
2575 parms->right->left->lvalue = 1;
2577 parms->opval.oprnd =
2578 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2580 parms->type = EX_OPERAND;
2583 /*-----------------------------------------------------------------*/
2584 /* geniCodeParms - generates parameters */
2585 /*-----------------------------------------------------------------*/
2587 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2595 /* if this is a param node then do the left & right */
2596 if (parms->type == EX_OP && parms->opval.op == PARAM)
2598 geniCodeParms (parms->left, stack, fetype, func,lvl);
2599 geniCodeParms (parms->right, stack, fetype, func,lvl);
2603 /* get the parameter value */
2604 if (parms->type == EX_OPERAND)
2605 pval = parms->opval.oprnd;
2608 /* maybe this else should go away ?? */
2609 /* hack don't like this but too lazy to think of
2611 if (IS_ADDRESS_OF_OP (parms))
2612 parms->left->lvalue = 1;
2614 if (IS_CAST_OP (parms) &&
2615 IS_PTR (parms->ftype) &&
2616 IS_ADDRESS_OF_OP (parms->right))
2617 parms->right->left->lvalue = 1;
2619 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2622 /* if register parm then make it a send */
2623 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2624 IS_REGPARM (parms->etype)) && !func->hasVargs)
2626 ic = newiCode (SEND, pval, NULL);
2631 /* now decide whether to push or assign */
2632 if (!(options.stackAuto || IS_RENT (fetype)))
2636 operand *top = operandFromSymbol (parms->argSym);
2637 geniCodeAssign (top, pval, 1);
2641 sym_link *p = operandType (pval);
2643 ic = newiCode (IPUSH, pval, NULL);
2645 /* update the stack adjustment */
2646 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2653 /*-----------------------------------------------------------------*/
2654 /* geniCodeCall - generates temp code for calling */
2655 /*-----------------------------------------------------------------*/
2657 geniCodeCall (operand * left, ast * parms,int lvl)
2661 sym_link *type, *etype;
2664 /* take care of parameters with side-effecting
2665 function calls in them, this is required to take care
2666 of overlaying function parameters */
2667 geniCodeSEParms (parms,lvl);
2669 /* first the parameters */
2670 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2672 /* now call : if symbol then pcall */
2673 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2674 ic = newiCode (PCALL, left, NULL);
2676 ic = newiCode (CALL, left, NULL);
2678 IC_ARGS (ic) = left->operand.symOperand->args;
2679 type = copyLinkChain (operandType (left)->next);
2680 etype = getSpec (type);
2681 SPEC_EXTR (etype) = 0;
2682 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2686 /* stack adjustment after call */
2687 ic->parmBytes = stack;
2692 /*-----------------------------------------------------------------*/
2693 /* geniCodeReceive - generate intermediate code for "receive" */
2694 /*-----------------------------------------------------------------*/
2696 geniCodeReceive (value * args)
2698 /* for all arguments that are passed in registers */
2702 if (IS_REGPARM (args->etype))
2704 operand *opr = operandFromValue (args);
2706 symbol *sym = OP_SYMBOL (opr);
2709 /* we will use it after all optimizations
2710 and before liveRange calculation */
2711 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2714 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2715 options.stackAuto == 0 &&
2716 /* !TARGET_IS_DS390) */
2717 (!(options.model == MODEL_FLAT24)) )
2722 opl = newiTempOperand (args->type, 0);
2724 sym->reqv->key = sym->key;
2725 OP_SYMBOL (sym->reqv)->key = sym->key;
2726 OP_SYMBOL (sym->reqv)->isreqv = 1;
2727 OP_SYMBOL (sym->reqv)->islocal = 0;
2728 SPIL_LOC (sym->reqv) = sym;
2732 ic = newiCode (RECEIVE, NULL, NULL);
2733 currFunc->recvSize = getSize (sym->etype);
2734 IC_RESULT (ic) = opr;
2742 /*-----------------------------------------------------------------*/
2743 /* geniCodeFunctionBody - create the function body */
2744 /*-----------------------------------------------------------------*/
2746 geniCodeFunctionBody (ast * tree,int lvl)
2753 /* reset the auto generation */
2759 func = ast2iCode (tree->left,lvl+1);
2760 fetype = getSpec (operandType (func));
2762 savelineno = lineno;
2763 lineno = OP_SYMBOL (func)->lineDef;
2764 /* create an entry label */
2765 geniCodeLabel (entryLabel);
2766 lineno = savelineno;
2768 /* create a proc icode */
2769 ic = newiCode (FUNCTION, func, NULL);
2770 /* if the function has parmas then */
2771 /* save the parameters information */
2772 ic->argLabel.args = tree->values.args;
2773 ic->lineno = OP_SYMBOL (func)->lineDef;
2777 /* for all parameters that are passed
2778 on registers add a "receive" */
2779 geniCodeReceive (tree->values.args);
2781 /* generate code for the body */
2782 ast2iCode (tree->right,lvl+1);
2784 /* create a label for return */
2785 geniCodeLabel (returnLabel);
2787 /* now generate the end proc */
2788 ic = newiCode (ENDFUNCTION, func, NULL);
2793 /*-----------------------------------------------------------------*/
2794 /* geniCodeReturn - gen icode for 'return' statement */
2795 /*-----------------------------------------------------------------*/
2797 geniCodeReturn (operand * op)
2801 /* if the operand is present force an rvalue */
2803 op = geniCodeRValue (op, FALSE);
2805 ic = newiCode (RETURN, op, NULL);
2809 /*-----------------------------------------------------------------*/
2810 /* geniCodeIfx - generates code for extended if statement */
2811 /*-----------------------------------------------------------------*/
2813 geniCodeIfx (ast * tree,int lvl)
2816 operand *condition = ast2iCode (tree->left,lvl+1);
2819 /* if condition is null then exit */
2823 condition = geniCodeRValue (condition, FALSE);
2825 cetype = getSpec (operandType (condition));
2826 /* if the condition is a literal */
2827 if (IS_LITERAL (cetype))
2829 if (floatFromVal (condition->operand.valOperand))
2831 if (tree->trueLabel)
2832 geniCodeGoto (tree->trueLabel);
2838 if (tree->falseLabel)
2839 geniCodeGoto (tree->falseLabel);
2846 if (tree->trueLabel)
2848 ic = newiCodeCondition (condition,
2853 if (tree->falseLabel)
2854 geniCodeGoto (tree->falseLabel);
2858 ic = newiCodeCondition (condition,
2865 ast2iCode (tree->right,lvl+1);
2868 /*-----------------------------------------------------------------*/
2869 /* geniCodeJumpTable - tries to create a jump table for switch */
2870 /*-----------------------------------------------------------------*/
2872 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2874 int min = 0, max = 0, t, cnt = 0;
2881 if (!tree || !caseVals)
2884 /* the criteria for creating a jump table is */
2885 /* all integer numbers between the maximum & minimum must */
2886 /* be present , the maximum value should not exceed 255 */
2887 min = max = (int) floatFromVal (vch = caseVals);
2888 sprintf (buffer, "_case_%d_%d",
2889 tree->values.switchVals.swNum,
2891 addSet (&labels, newiTempLabel (buffer));
2893 /* if there is only one case value then no need */
2894 if (!(vch = vch->next))
2899 if (((t = (int) floatFromVal (vch)) - max) != 1)
2901 sprintf (buffer, "_case_%d_%d",
2902 tree->values.switchVals.swNum,
2904 addSet (&labels, newiTempLabel (buffer));
2910 /* if the number of case statements <= 2 then */
2911 /* it is not economical to create the jump table */
2912 /* since two compares are needed for boundary conditions */
2913 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2916 if (tree->values.switchVals.swDefault)
2917 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2919 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2921 falseLabel = newiTempLabel (buffer);
2923 /* so we can create a jumptable */
2924 /* first we rule out the boundary conditions */
2925 /* if only optimization says so */
2926 if (!optimize.noJTabBoundary)
2928 sym_link *cetype = getSpec (operandType (cond));
2929 /* no need to check the lower bound if
2930 the condition is unsigned & minimum value is zero */
2931 if (!(min == 0 && SPEC_USIGN (cetype)))
2933 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2934 ic = newiCodeCondition (boundary, falseLabel, NULL);
2938 /* now for upper bounds */
2939 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
2940 ic = newiCodeCondition (boundary, falseLabel, NULL);
2944 /* if the min is not zero then we no make it zero */
2947 cond = geniCodeSubtract (cond, operandFromLit (min));
2948 setOperandType (cond, UCHARTYPE);
2951 /* now create the jumptable */
2952 ic = newiCode (JUMPTABLE, NULL, NULL);
2953 IC_JTCOND (ic) = cond;
2954 IC_JTLABELS (ic) = labels;
2959 /*-----------------------------------------------------------------*/
2960 /* geniCodeSwitch - changes a switch to a if statement */
2961 /*-----------------------------------------------------------------*/
2963 geniCodeSwitch (ast * tree,int lvl)
2966 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
2967 value *caseVals = tree->values.switchVals.swVals;
2968 symbol *trueLabel, *falseLabel;
2970 /* if we can make this a jump table */
2971 if (geniCodeJumpTable (cond, caseVals, tree))
2972 goto jumpTable; /* no need for the comparison */
2974 /* for the cases defined do */
2978 operand *compare = geniCodeLogic (cond,
2979 operandFromValue (caseVals),
2982 sprintf (buffer, "_case_%d_%d",
2983 tree->values.switchVals.swNum,
2984 (int) floatFromVal (caseVals));
2985 trueLabel = newiTempLabel (buffer);
2987 ic = newiCodeCondition (compare, trueLabel, NULL);
2989 caseVals = caseVals->next;
2994 /* if default is present then goto break else break */
2995 if (tree->values.switchVals.swDefault)
2996 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2998 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3000 falseLabel = newiTempLabel (buffer);
3001 geniCodeGoto (falseLabel);
3004 ast2iCode (tree->right,lvl+1);
3007 /*-----------------------------------------------------------------*/
3008 /* geniCodeInline - intermediate code for inline assembler */
3009 /*-----------------------------------------------------------------*/
3011 geniCodeInline (ast * tree)
3015 ic = newiCode (INLINEASM, NULL, NULL);
3016 IC_INLINE (ic) = tree->values.inlineasm;
3020 /*-----------------------------------------------------------------*/
3021 /* geniCodeArrayInit - intermediate code for array initializer */
3022 /*-----------------------------------------------------------------*/
3024 geniCodeArrayInit (ast * tree, operand *array)
3028 ic = newiCode (ARRAYINIT, array, NULL);
3029 IC_ARRAYILIST (ic) = tree->values.constlist;
3033 /*-----------------------------------------------------------------*/
3034 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3035 /* particular case. Ie : assigning or dereferencing array or ptr */
3036 /*-----------------------------------------------------------------*/
3037 set * lvaluereqSet = NULL;
3038 typedef struct lvalItem
3045 /*-----------------------------------------------------------------*/
3046 /* addLvaluereq - add a flag for lvalreq for current ast level */
3047 /*-----------------------------------------------------------------*/
3048 void addLvaluereq(int lvl)
3050 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3053 addSetHead(&lvaluereqSet,lpItem);
3056 /*-----------------------------------------------------------------*/
3057 /* delLvaluereq - del a flag for lvalreq for current ast level */
3058 /*-----------------------------------------------------------------*/
3062 lpItem = getSet(&lvaluereqSet);
3063 if(lpItem) free(lpItem);
3065 /*-----------------------------------------------------------------*/
3066 /* clearLvaluereq - clear lvalreq flag */
3067 /*-----------------------------------------------------------------*/
3068 void clearLvaluereq()
3071 lpItem = peekSet(lvaluereqSet);
3072 if(lpItem) lpItem->req = 0;
3074 /*-----------------------------------------------------------------*/
3075 /* getLvaluereq - get the last lvalreq level */
3076 /*-----------------------------------------------------------------*/
3077 int getLvaluereqLvl()
3080 lpItem = peekSet(lvaluereqSet);
3081 if(lpItem) return lpItem->lvl;
3084 /*-----------------------------------------------------------------*/
3085 /* isLvaluereq - is lvalreq valid for this level ? */
3086 /*-----------------------------------------------------------------*/
3087 int isLvaluereq(int lvl)
3090 lpItem = peekSet(lvaluereqSet);
3091 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3095 /*-----------------------------------------------------------------*/
3096 /* ast2iCode - creates an icodeList from an ast */
3097 /*-----------------------------------------------------------------*/
3099 ast2iCode (ast * tree,int lvl)
3101 operand *left = NULL;
3102 operand *right = NULL;
3105 /* set the global variables for filename & line number */
3107 filename = tree->filename;
3109 lineno = tree->lineno;
3111 block = tree->block;
3113 scopeLevel = tree->level;
3115 if (tree->type == EX_VALUE)
3116 return operandFromValue (tree->opval.val);
3118 if (tree->type == EX_LINK)
3119 return operandFromLink (tree->opval.lnk);
3121 /* if we find a nullop */
3122 if (tree->type == EX_OP &&
3123 (tree->opval.op == NULLOP ||
3124 tree->opval.op == BLOCK))
3126 ast2iCode (tree->left,lvl+1);
3127 ast2iCode (tree->right,lvl+1);
3131 /* special cases for not evaluating */
3132 if (tree->opval.op != ':' &&
3133 tree->opval.op != '?' &&
3134 tree->opval.op != CALL &&
3135 tree->opval.op != IFX &&
3136 tree->opval.op != LABEL &&
3137 tree->opval.op != GOTO &&
3138 tree->opval.op != SWITCH &&
3139 tree->opval.op != FUNCTION &&
3140 tree->opval.op != INLINEASM)
3143 if (IS_ASSIGN_OP (tree->opval.op) ||
3144 IS_DEREF_OP (tree) ||
3145 (tree->opval.op == '&' && !tree->right) ||
3146 tree->opval.op == PTR_OP)
3149 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3150 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3153 left = operandFromAst (tree->left,lvl);
3155 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3156 left = geniCodeRValue (left, TRUE);
3160 left = operandFromAst (tree->left,lvl);
3162 if (tree->opval.op == INC_OP ||
3163 tree->opval.op == DEC_OP)
3166 right = operandFromAst (tree->right,lvl);
3171 right = operandFromAst (tree->right,lvl);
3175 /* now depending on the type of operand */
3176 /* this will be a biggy */
3177 switch (tree->opval.op)
3180 case '[': /* array operation */
3182 sym_link *ltype = operandType (left);
3183 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3184 right = geniCodeRValue (right, TRUE);
3187 return geniCodeArray (left, right,lvl);
3189 case '.': /* structure dereference */
3190 if (IS_PTR (operandType (left)))
3191 left = geniCodeRValue (left, TRUE);
3193 left = geniCodeRValue (left, FALSE);
3195 return geniCodeStruct (left, right, tree->lvalue);
3197 case PTR_OP: /* structure pointer dereference */
3200 pType = operandType (left);
3201 left = geniCodeRValue (left, TRUE);
3203 setOClass (pType, getSpec (operandType (left)));
3206 return geniCodeStruct (left, right, tree->lvalue);
3208 case INC_OP: /* increment operator */
3210 return geniCodePostInc (left);
3212 return geniCodePreInc (right);
3214 case DEC_OP: /* decrement operator */
3216 return geniCodePostDec (left);
3218 return geniCodePreDec (right);
3220 case '&': /* bitwise and or address of operator */
3222 { /* this is a bitwise operator */
3223 left = geniCodeRValue (left, FALSE);
3224 right = geniCodeRValue (right, FALSE);
3225 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3228 return geniCodeAddressOf (left);
3230 case '|': /* bitwise or & xor */
3232 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3233 geniCodeRValue (right, FALSE),
3238 return geniCodeDivision (geniCodeRValue (left, FALSE),
3239 geniCodeRValue (right, FALSE));
3242 return geniCodeModulus (geniCodeRValue (left, FALSE),
3243 geniCodeRValue (right, FALSE));
3246 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3247 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3249 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3253 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3254 geniCodeRValue (right, FALSE));
3256 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3260 return geniCodeAdd (geniCodeRValue (left, FALSE),
3261 geniCodeRValue (right, FALSE),lvl);
3263 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3266 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3267 geniCodeRValue (right, FALSE));
3270 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3271 geniCodeRValue (right, FALSE));
3273 return geniCodeCast (operandType (left),
3274 geniCodeRValue (right, FALSE), FALSE);
3280 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3284 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3285 setOperandType (op, UCHARTYPE);
3296 return geniCodeLogic (geniCodeRValue (left, FALSE),
3297 geniCodeRValue (right, FALSE),
3300 return geniCodeConditional (tree,lvl);
3303 return operandFromLit (getSize (tree->right->ftype));
3307 sym_link *rtype = operandType (right);
3308 sym_link *ltype = operandType (left);
3309 if (IS_PTR (rtype) && IS_ITEMP (right)
3310 && right->isaddr && compareType (rtype->next, ltype) == 1)
3311 right = geniCodeRValue (right, TRUE);
3313 right = geniCodeRValue (right, FALSE);
3315 geniCodeAssign (left, right, 0);
3320 geniCodeAssign (left,
3321 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3323 geniCodeRValue (right, FALSE),FALSE), 0);
3327 geniCodeAssign (left,
3328 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3330 geniCodeRValue (right, FALSE)), 0);
3333 geniCodeAssign (left,
3334 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3336 geniCodeRValue (right, FALSE)), 0);
3339 sym_link *rtype = operandType (right);
3340 sym_link *ltype = operandType (left);
3341 if (IS_PTR (rtype) && IS_ITEMP (right)
3342 && right->isaddr && compareType (rtype->next, ltype) == 1)
3343 right = geniCodeRValue (right, TRUE);
3345 right = geniCodeRValue (right, FALSE);
3348 return geniCodeAssign (left,
3349 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3355 sym_link *rtype = operandType (right);
3356 sym_link *ltype = operandType (left);
3357 if (IS_PTR (rtype) && IS_ITEMP (right)
3358 && right->isaddr && compareType (rtype->next, ltype) == 1)
3360 right = geniCodeRValue (right, TRUE);
3364 right = geniCodeRValue (right, FALSE);
3367 geniCodeAssign (left,
3368 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3374 geniCodeAssign (left,
3375 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3377 geniCodeRValue (right, FALSE)), 0);
3380 geniCodeAssign (left,
3381 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3383 geniCodeRValue (right, FALSE)), 0);
3386 geniCodeAssign (left,
3387 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3389 geniCodeRValue (right, FALSE),
3391 operandType (left)), 0);
3394 geniCodeAssign (left,
3395 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3397 geniCodeRValue (right, FALSE),
3399 operandType (left)), 0);
3402 geniCodeAssign (left,
3403 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3405 geniCodeRValue (right, FALSE),
3407 operandType (left)), 0);
3409 return geniCodeRValue (right, FALSE);
3412 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3415 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3416 return ast2iCode (tree->right,lvl+1);
3419 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3420 return ast2iCode (tree->right,lvl+1);
3423 geniCodeFunctionBody (tree,lvl);
3427 geniCodeReturn (right);
3431 geniCodeIfx (tree,lvl);
3435 geniCodeSwitch (tree,lvl);
3439 geniCodeInline (tree);
3443 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3450 /*-----------------------------------------------------------------*/
3451 /* reverseICChain - gets from the list and creates a linkedlist */
3452 /*-----------------------------------------------------------------*/
3459 while ((loop = getSet (&iCodeChain)))
3471 /*-----------------------------------------------------------------*/
3472 /* iCodeFromAst - given an ast will convert it to iCode */
3473 /*-----------------------------------------------------------------*/
3475 iCodeFromAst (ast * tree)
3477 returnLabel = newiTempLabel ("_return");
3478 entryLabel = newiTempLabel ("_entry");
3480 return reverseiCChain ();