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)) && (!TARGET_IS_DS390)) &&
1189 options.stackAuto == 0)
1192 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1193 !IS_FUNC (sym->type) && /* not a function */
1194 !sym->_isparm && /* not a parameter */
1195 sym->level && /* is a local variable */
1196 !sym->addrtaken && /* whose address has not been taken */
1197 !sym->reqv && /* does not already have a register euivalence */
1198 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1199 !IS_STATIC (sym->etype) && /* and not declared static */
1200 !sym->islbl && /* not a label */
1201 ok && /* farspace check */
1202 !IS_BITVAR (sym->etype) /* not a bit variable */
1206 /* we will use it after all optimizations
1207 and before liveRange calculation */
1208 sym->reqv = newiTempOperand (sym->type, 0);
1209 sym->reqv->key = sym->key;
1210 OP_SYMBOL (sym->reqv)->key = sym->key;
1211 OP_SYMBOL (sym->reqv)->isreqv = 1;
1212 OP_SYMBOL (sym->reqv)->islocal = 1;
1213 SPIL_LOC (sym->reqv) = sym;
1216 if (!IS_AGGREGATE (sym->type))
1220 op->operand.symOperand = sym;
1223 op->isvolatile = isOperandVolatile (op, TRUE);
1224 op->isGlobal = isOperandGlobal (op);
1225 op->isPtr = IS_PTR (operandType (op));
1226 op->isParm = sym->_isparm;
1231 /* itemp = &[_symbol] */
1233 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1234 IC_LEFT (ic)->type = SYMBOL;
1235 IC_LEFT (ic)->operand.symOperand = sym;
1236 IC_LEFT (ic)->key = sym->key;
1237 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1238 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1239 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1242 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1243 if (IS_ARRAY (sym->type))
1245 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1246 IC_RESULT (ic)->isaddr = 0;
1249 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1251 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1255 return IC_RESULT (ic);
1258 /*-----------------------------------------------------------------*/
1259 /* operandFromValue - creates an operand from value */
1260 /*-----------------------------------------------------------------*/
1262 operandFromValue (value * val)
1266 /* if this is a symbol then do the symbol thing */
1268 return operandFromSymbol (val->sym);
1270 /* this is not a symbol */
1273 op->operand.valOperand = val;
1274 op->isLiteral = isOperandLiteral (op);
1278 /*-----------------------------------------------------------------*/
1279 /* operandFromLink - operand from typeChain */
1280 /*-----------------------------------------------------------------*/
1282 operandFromLink (sym_link * type)
1286 /* operand from sym_link */
1292 op->operand.typeOperand = copyLinkChain (type);
1296 /*-----------------------------------------------------------------*/
1297 /* operandFromLit - makes an operand from a literal value */
1298 /*-----------------------------------------------------------------*/
1300 operandFromLit (double i)
1302 return operandFromValue (valueFromLit (i));
1305 /*-----------------------------------------------------------------*/
1306 /* operandFromAst - creates an operand from an ast */
1307 /*-----------------------------------------------------------------*/
1309 operandFromAst (ast * tree,int lvl)
1315 /* depending on type do */
1319 return ast2iCode (tree,lvl+1);
1323 return operandFromValue (tree->opval.val);
1327 return operandFromLink (tree->opval.lnk);
1331 /* Just to keep the comiler happy */
1332 return (operand *) 0;
1335 /*-----------------------------------------------------------------*/
1336 /* setOperandType - sets the operand's type to the given type */
1337 /*-----------------------------------------------------------------*/
1339 setOperandType (operand * op, sym_link * type)
1341 /* depending on the type of operand */
1346 op->operand.valOperand->etype =
1347 getSpec (op->operand.valOperand->type =
1348 copyLinkChain (type));
1352 if (op->operand.symOperand->isitmp)
1353 op->operand.symOperand->etype =
1354 getSpec (op->operand.symOperand->type =
1355 copyLinkChain (type));
1357 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1358 "attempt to modify type of source");
1362 op->operand.typeOperand = copyLinkChain (type);
1367 /*-----------------------------------------------------------------*/
1368 /* Get size in byte of ptr need to access an array */
1369 /*-----------------------------------------------------------------*/
1371 getArraySizePtr (operand * op)
1373 sym_link *ltype = operandType(op);
1377 int size = getSize(ltype);
1378 return(IS_GENPTR(ltype)?(size-1):size);
1383 sym_link *letype = getSpec(ltype);
1384 switch (PTR_TYPE (SPEC_OCLS (letype)))
1396 return (GPTRSIZE-1);
1405 /*-----------------------------------------------------------------*/
1406 /* perform "usual unary conversions" */
1407 /*-----------------------------------------------------------------*/
1409 usualUnaryConversions (operand * op)
1411 if (IS_INTEGRAL (operandType (op)))
1413 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1416 return geniCodeCast (INTTYPE, op, TRUE);
1422 /*-----------------------------------------------------------------*/
1423 /* perform "usual binary conversions" */
1424 /*-----------------------------------------------------------------*/
1426 usualBinaryConversions (operand ** op1, operand ** op2)
1429 sym_link *rtype = operandType (*op2);
1430 sym_link *ltype = operandType (*op1);
1432 ctype = computeType (ltype, rtype);
1433 *op1 = geniCodeCast (ctype, *op1, TRUE);
1434 *op2 = geniCodeCast (ctype, *op2, TRUE);
1439 /*-----------------------------------------------------------------*/
1440 /* geniCodeValueAtAddress - generate intermeditate code for value */
1442 /*-----------------------------------------------------------------*/
1444 geniCodeRValue (operand * op, bool force)
1447 sym_link *type = operandType (op);
1448 sym_link *etype = getSpec (type);
1450 /* if this is an array & already */
1451 /* an address then return this */
1452 if (IS_AGGREGATE (type) ||
1453 (IS_PTR (type) && !force && !op->isaddr))
1454 return operandFromOperand (op);
1456 /* if this is not an address then must be */
1457 /* rvalue already so return this one */
1461 /* if this is not a temp symbol then */
1462 if (!IS_ITEMP (op) &&
1464 !IN_FARSPACE (SPEC_OCLS (etype)))
1466 op = operandFromOperand (op);
1471 if (IS_SPEC (type) &&
1472 IS_TRUE_SYMOP (op) &&
1473 (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
1475 op = operandFromOperand (op);
1480 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1481 if (IS_PTR (type) && op->isaddr && force)
1484 type = copyLinkChain (type);
1486 IC_RESULT (ic) = newiTempOperand (type, 1);
1487 IC_RESULT (ic)->isaddr = 0;
1489 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1491 /* if the right is a symbol */
1492 if (op->type == SYMBOL)
1493 IC_RESULT (ic)->operand.symOperand->args =
1494 op->operand.symOperand->args;
1497 return IC_RESULT (ic);
1500 /*-----------------------------------------------------------------*/
1501 /* geniCodeCast - changes the value from one type to another */
1502 /*-----------------------------------------------------------------*/
1504 geniCodeCast (sym_link * type, operand * op, bool implicit)
1508 sym_link *opetype = getSpec (optype = operandType (op));
1511 /* one of them has size zero then error */
1512 if (IS_VOID (optype))
1514 werror (E_CAST_ZERO);
1518 /* if the operand is already the desired type then do nothing */
1519 if (compareType (type, optype) == 1)
1522 /* if this is a literal then just change the type & return */
1523 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1524 return operandFromValue (valCastLiteral (type,
1525 operandLitValue (op)));
1527 /* if casting to some pointer type &&
1528 the destination is not a generic pointer
1529 then give a warning : (only for implicit casts) */
1530 if (IS_PTR (optype) && implicit &&
1531 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1534 werror (E_INCOMPAT_CAST);
1535 fprintf (stderr, "from type '");
1536 printTypeChain (optype, stderr);
1537 fprintf (stderr, "' to type '");
1538 printTypeChain (type, stderr);
1539 fprintf (stderr, "'\n");
1542 /* if they are the same size create an assignment */
1543 if (getSize (type) == getSize (optype) &&
1544 !IS_BITFIELD (type) &&
1546 !IS_FLOAT (optype) &&
1547 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1548 (!IS_SPEC (type) && !IS_SPEC (optype))))
1551 ic = newiCode ('=', NULL, op);
1552 IC_RESULT (ic) = newiTempOperand (type, 0);
1553 SPIL_LOC (IC_RESULT (ic)) =
1554 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1555 IC_RESULT (ic)->isaddr = 0;
1559 ic = newiCode (CAST, operandFromLink (type),
1560 geniCodeRValue (op, FALSE));
1562 IC_RESULT (ic) = newiTempOperand (type, 0);
1565 /* preserve the storage class & output class */
1566 /* of the original variable */
1567 restype = getSpec (operandType (IC_RESULT (ic)));
1568 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1569 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1572 return IC_RESULT (ic);
1575 /*-----------------------------------------------------------------*/
1576 /* geniCodeLabel - will create a Label */
1577 /*-----------------------------------------------------------------*/
1579 geniCodeLabel (symbol * label)
1583 ic = newiCodeLabelGoto (LABEL, label);
1587 /*-----------------------------------------------------------------*/
1588 /* geniCodeGoto - will create a Goto */
1589 /*-----------------------------------------------------------------*/
1591 geniCodeGoto (symbol * label)
1595 ic = newiCodeLabelGoto (GOTO, label);
1599 /*-----------------------------------------------------------------*/
1600 /* geniCodeMultiply - gen intermediate code for multiplication */
1601 /*-----------------------------------------------------------------*/
1603 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1610 /* if they are both literal then we know the result */
1611 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1612 return operandFromValue (valMult (left->operand.valOperand,
1613 right->operand.valOperand));
1615 if (IS_LITERAL(retype)) {
1616 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1619 resType = usualBinaryConversions (&left, &right);
1621 rtype = operandType (right);
1622 retype = getSpec (rtype);
1623 ltype = operandType (left);
1624 letype = getSpec (ltype);
1628 SPEC_NOUN(getSpec(resType))=V_INT;
1631 /* if the right is a literal & power of 2 */
1632 /* then make it a left shift */
1633 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1634 efficient in most cases than 2 bytes result = 2 bytes << literal
1635 if port has 1 byte muldiv */
1636 if (p2 && !IS_FLOAT (letype) &&
1637 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1638 (port->support.muldiv == 1)))
1640 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1642 /* LEFT_OP need same size for left and result, */
1643 left = geniCodeCast (resType, left, TRUE);
1644 ltype = operandType (left);
1646 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1650 ic = newiCode ('*', left, right); /* normal multiplication */
1651 /* if the size left or right > 1 then support routine */
1652 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1656 IC_RESULT (ic) = newiTempOperand (resType, 1);
1659 return IC_RESULT (ic);
1662 /*-----------------------------------------------------------------*/
1663 /* geniCodeDivision - gen intermediate code for division */
1664 /*-----------------------------------------------------------------*/
1666 geniCodeDivision (operand * left, operand * right)
1671 sym_link *rtype = operandType (right);
1672 sym_link *retype = getSpec (rtype);
1673 sym_link *ltype = operandType (left);
1674 sym_link *letype = getSpec (ltype);
1676 resType = usualBinaryConversions (&left, &right);
1678 /* if the right is a literal & power of 2 */
1679 /* then make it a right shift */
1680 if (IS_LITERAL (retype) &&
1681 !IS_FLOAT (letype) &&
1682 (p2 = powof2 ((unsigned long)
1683 floatFromVal (right->operand.valOperand)))) {
1684 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1688 ic = newiCode ('/', left, right); /* normal division */
1689 /* if the size left or right > 1 then support routine */
1690 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1693 IC_RESULT (ic) = newiTempOperand (resType, 0);
1696 return IC_RESULT (ic);
1698 /*-----------------------------------------------------------------*/
1699 /* geniCodeModulus - gen intermediate code for modulus */
1700 /*-----------------------------------------------------------------*/
1702 geniCodeModulus (operand * left, operand * right)
1708 /* if they are both literal then we know the result */
1709 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1710 return operandFromValue (valMod (left->operand.valOperand,
1711 right->operand.valOperand));
1713 resType = usualBinaryConversions (&left, &right);
1715 /* now they are the same size */
1716 ic = newiCode ('%', left, right);
1718 /* if the size left or right > 1 then support routine */
1719 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1721 IC_RESULT (ic) = newiTempOperand (resType, 0);
1724 return IC_RESULT (ic);
1727 /*-----------------------------------------------------------------*/
1728 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1729 /*-----------------------------------------------------------------*/
1731 geniCodePtrPtrSubtract (operand * left, operand * right)
1737 /* if they are both literals then */
1738 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1740 result = operandFromValue (valMinus (left->operand.valOperand,
1741 right->operand.valOperand));
1745 ic = newiCode ('-', left, right);
1747 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1751 return geniCodeDivision (result,
1752 operandFromLit (getSize (ltype->next)));
1755 /*-----------------------------------------------------------------*/
1756 /* geniCodeSubtract - generates code for subtraction */
1757 /*-----------------------------------------------------------------*/
1759 geniCodeSubtract (operand * left, operand * right)
1766 /* if they both pointers then */
1767 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1768 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1769 return geniCodePtrPtrSubtract (left, right);
1771 /* if they are both literal then we know the result */
1772 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1773 && left->isLiteral && right->isLiteral)
1774 return operandFromValue (valMinus (left->operand.valOperand,
1775 right->operand.valOperand));
1777 /* if left is an array or pointer */
1778 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1780 isarray = left->isaddr;
1781 right = geniCodeMultiply (right,
1782 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1783 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1786 { /* make them the same size */
1787 resType = usualBinaryConversions (&left, &right);
1790 ic = newiCode ('-', left, right);
1792 IC_RESULT (ic) = newiTempOperand (resType, 1);
1793 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1795 /* if left or right is a float */
1796 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1800 return IC_RESULT (ic);
1803 /*-----------------------------------------------------------------*/
1804 /* geniCodeAdd - generates iCode for addition */
1805 /*-----------------------------------------------------------------*/
1807 geniCodeAdd (operand * left, operand * right,int lvl)
1815 /* if left is an array then array access */
1816 if (IS_ARRAY (ltype))
1817 return geniCodeArray (left, right,lvl);
1819 /* if the right side is LITERAL zero */
1820 /* return the left side */
1821 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1824 /* if left is literal zero return right */
1825 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1828 /* if left is an array or pointer then size */
1831 isarray = left->isaddr;
1832 // there is no need to multiply with 1
1833 if (getSize(ltype->next)!=1) {
1834 size = operandFromLit (getSize (ltype->next));
1835 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1837 resType = copyLinkChain (ltype);
1840 { /* make them the same size */
1841 resType = usualBinaryConversions (&left, &right);
1844 /* if they are both literals then we know */
1845 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1846 && left->isLiteral && right->isLiteral)
1847 return operandFromValue (valPlus (valFromType (letype),
1848 valFromType (retype)));
1850 ic = newiCode ('+', left, right);
1852 IC_RESULT (ic) = newiTempOperand (resType, 1);
1853 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1855 /* if left or right is a float then support
1857 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1862 return IC_RESULT (ic);
1866 /*-----------------------------------------------------------------*/
1867 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1868 /*-----------------------------------------------------------------*/
1870 aggrToPtr (sym_link * type, bool force)
1876 if (IS_PTR (type) && !force)
1879 etype = getSpec (type);
1883 /* if the output class is generic */
1884 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1885 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1887 /* if the variable was declared a constant */
1888 /* then the pointer points to a constant */
1889 if (IS_CONSTANT (etype))
1890 DCL_PTR_CONST (ptype) = 1;
1892 /* the variable was volatile then pointer to volatile */
1893 if (IS_VOLATILE (etype))
1894 DCL_PTR_VOLATILE (ptype) = 1;
1898 /*-----------------------------------------------------------------*/
1899 /* geniCodeArray2Ptr - array to pointer */
1900 /*-----------------------------------------------------------------*/
1902 geniCodeArray2Ptr (operand * op)
1904 sym_link *optype = operandType (op);
1905 sym_link *opetype = getSpec (optype);
1907 /* set the pointer depending on the storage class */
1908 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1909 DCL_PTR_CONST (optype) = port->mem.code_ro;
1912 /* if the variable was declared a constant */
1913 /* then the pointer points to a constant */
1914 if (IS_CONSTANT (opetype))
1915 DCL_PTR_CONST (optype) = 1;
1917 /* the variable was volatile then pointer to volatile */
1918 if (IS_VOLATILE (opetype))
1919 DCL_PTR_VOLATILE (optype) = 1;
1925 /*-----------------------------------------------------------------*/
1926 /* geniCodeArray - array access */
1927 /*-----------------------------------------------------------------*/
1929 geniCodeArray (operand * left, operand * right,int lvl)
1932 sym_link *ltype = operandType (left);
1936 if (IS_PTR (ltype->next) && left->isaddr)
1938 left = geniCodeRValue (left, FALSE);
1940 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
1943 right = geniCodeMultiply (right,
1944 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1946 /* we can check for limits here */
1947 if (isOperandLiteral (right) &&
1950 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
1952 werror (E_ARRAY_BOUND);
1953 right = operandFromLit (0);
1956 ic = newiCode ('+', left, right);
1958 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
1959 !IS_AGGREGATE (ltype->next) &&
1960 !IS_PTR (ltype->next))
1961 ? ltype : ltype->next), 0);
1963 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
1965 return IC_RESULT (ic);
1968 /*-----------------------------------------------------------------*/
1969 /* geniCodeStruct - generates intermediate code for structres */
1970 /*-----------------------------------------------------------------*/
1972 geniCodeStruct (operand * left, operand * right, bool islval)
1975 sym_link *type = operandType (left);
1976 sym_link *etype = getSpec (type);
1978 symbol *element = getStructElement (SPEC_STRUCT (etype),
1979 right->operand.symOperand);
1981 /* add the offset */
1982 ic = newiCode ('+', left, operandFromLit (element->offset));
1984 IC_RESULT (ic) = newiTempOperand (element->type, 0);
1986 /* preserve the storage & output class of the struct */
1987 /* as well as the volatile attribute */
1988 retype = getSpec (operandType (IC_RESULT (ic)));
1989 SPEC_SCLS (retype) = SPEC_SCLS (etype);
1990 SPEC_OCLS (retype) = SPEC_OCLS (etype);
1991 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
1993 if (IS_PTR (element->type))
1994 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1996 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2000 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2003 /*-----------------------------------------------------------------*/
2004 /* geniCodePostInc - generate int code for Post increment */
2005 /*-----------------------------------------------------------------*/
2007 geniCodePostInc (operand * op)
2011 sym_link *optype = operandType (op);
2013 operand *rv = (IS_ITEMP (op) ?
2014 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2016 sym_link *rvtype = operandType (rv);
2019 /* if this is not an address we have trouble */
2022 werror (E_LVALUE_REQUIRED, "++");
2026 rOp = newiTempOperand (rvtype, 0);
2027 OP_SYMBOL(rOp)->noSpilLoc = 1;
2030 OP_SYMBOL(rv)->noSpilLoc = 1;
2032 geniCodeAssign (rOp, rv, 0);
2034 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2035 if (IS_FLOAT (rvtype))
2036 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2038 ic = newiCode ('+', rv, operandFromLit (size));
2040 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2043 geniCodeAssign (op, result, 0);
2049 /*-----------------------------------------------------------------*/
2050 /* geniCodePreInc - generate code for preIncrement */
2051 /*-----------------------------------------------------------------*/
2053 geniCodePreInc (operand * op)
2056 sym_link *optype = operandType (op);
2057 operand *rop = (IS_ITEMP (op) ?
2058 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2060 sym_link *roptype = operandType (rop);
2066 werror (E_LVALUE_REQUIRED, "++");
2071 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2072 if (IS_FLOAT (roptype))
2073 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2075 ic = newiCode ('+', rop, operandFromLit (size));
2076 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2080 return geniCodeAssign (op, result, 0);
2083 /*-----------------------------------------------------------------*/
2084 /* geniCodePostDec - generates code for Post decrement */
2085 /*-----------------------------------------------------------------*/
2087 geniCodePostDec (operand * op)
2091 sym_link *optype = operandType (op);
2093 operand *rv = (IS_ITEMP (op) ?
2094 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2096 sym_link *rvtype = operandType (rv);
2099 /* if this is not an address we have trouble */
2102 werror (E_LVALUE_REQUIRED, "++");
2106 rOp = newiTempOperand (rvtype, 0);
2107 OP_SYMBOL(rOp)->noSpilLoc = 1;
2110 OP_SYMBOL(rv)->noSpilLoc = 1;
2112 geniCodeAssign (rOp, rv, 0);
2114 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2115 if (IS_FLOAT (rvtype))
2116 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2118 ic = newiCode ('-', rv, operandFromLit (size));
2120 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2123 geniCodeAssign (op, result, 0);
2129 /*-----------------------------------------------------------------*/
2130 /* geniCodePreDec - generate code for pre decrement */
2131 /*-----------------------------------------------------------------*/
2133 geniCodePreDec (operand * op)
2136 sym_link *optype = operandType (op);
2137 operand *rop = (IS_ITEMP (op) ?
2138 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2140 sym_link *roptype = operandType (rop);
2146 werror (E_LVALUE_REQUIRED, "++");
2151 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2152 if (IS_FLOAT (roptype))
2153 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2155 ic = newiCode ('-', rop, operandFromLit (size));
2156 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2160 return geniCodeAssign (op, result, 0);
2164 /*-----------------------------------------------------------------*/
2165 /* geniCodeBitwise - gen int code for bitWise operators */
2166 /*-----------------------------------------------------------------*/
2168 geniCodeBitwise (operand * left, operand * right,
2169 int oper, sym_link * resType)
2173 left = geniCodeCast (resType, left, TRUE);
2174 right = geniCodeCast (resType, right, TRUE);
2176 ic = newiCode (oper, left, right);
2177 IC_RESULT (ic) = newiTempOperand (resType, 0);
2180 return IC_RESULT (ic);
2183 /*-----------------------------------------------------------------*/
2184 /* geniCodeAddressOf - gens icode for '&' address of operator */
2185 /*-----------------------------------------------------------------*/
2187 geniCodeAddressOf (operand * op)
2191 sym_link *optype = operandType (op);
2192 sym_link *opetype = getSpec (optype);
2194 /* lvalue check already done in decorateType */
2195 /* this must be a lvalue */
2196 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2197 /* werror (E_LVALUE_REQUIRED,"&"); */
2202 p->class = DECLARATOR;
2204 /* set the pointer depending on the storage class */
2205 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2206 DCL_PTR_CONST (p) = port->mem.code_ro;
2208 /* make sure we preserve the const & volatile */
2209 if (IS_CONSTANT (opetype))
2210 DCL_PTR_CONST (p) = 1;
2212 if (IS_VOLATILE (opetype))
2213 DCL_PTR_VOLATILE (p) = 1;
2215 p->next = copyLinkChain (optype);
2217 /* if already a temp */
2220 setOperandType (op, p);
2225 /* other wise make this of the type coming in */
2226 ic = newiCode (ADDRESS_OF, op, NULL);
2227 IC_RESULT (ic) = newiTempOperand (p, 1);
2228 IC_RESULT (ic)->isaddr = 0;
2230 return IC_RESULT (ic);
2232 /*-----------------------------------------------------------------*/
2233 /* setOClass - sets the output class depending on the pointer type */
2234 /*-----------------------------------------------------------------*/
2236 setOClass (sym_link * ptr, sym_link * spec)
2238 switch (DCL_TYPE (ptr))
2241 SPEC_OCLS (spec) = data;
2245 SPEC_OCLS (spec) = generic;
2249 SPEC_OCLS (spec) = xdata;
2253 SPEC_OCLS (spec) = code;
2257 SPEC_OCLS (spec) = idata;
2261 SPEC_OCLS (spec) = xstack;
2265 SPEC_OCLS (spec) = eeprom;
2274 /*-----------------------------------------------------------------*/
2275 /* geniCodeDerefPtr - dereference pointer with '*' */
2276 /*-----------------------------------------------------------------*/
2278 geniCodeDerefPtr (operand * op,int lvl)
2280 sym_link *rtype, *retype;
2281 sym_link *optype = operandType (op);
2283 /* if this is a pointer then generate the rvalue */
2284 if (IS_PTR (optype))
2286 if (IS_TRUE_SYMOP (op))
2289 op = geniCodeRValue (op, TRUE);
2292 op = geniCodeRValue (op, TRUE);
2295 /* now get rid of the pointer part */
2296 if (isLvaluereq(lvl) && IS_ITEMP (op))
2298 retype = getSpec (rtype = copyLinkChain (optype));
2302 retype = getSpec (rtype = copyLinkChain (optype->next));
2305 /* if this is a pointer then outputclass needs 2b updated */
2306 if (IS_PTR (optype))
2307 setOClass (optype, retype);
2309 op->isGptr = IS_GENPTR (optype);
2311 /* if the pointer was declared as a constant */
2312 /* then we cannot allow assignment to the derefed */
2313 if (IS_PTR_CONST (optype))
2314 SPEC_CONST (retype) = 1;
2316 op->isaddr = (IS_PTR (rtype) ||
2317 IS_STRUCT (rtype) ||
2322 if (!isLvaluereq(lvl))
2323 op = geniCodeRValue (op, TRUE);
2325 setOperandType (op, rtype);
2330 /*-----------------------------------------------------------------*/
2331 /* geniCodeUnaryMinus - does a unary minus of the operand */
2332 /*-----------------------------------------------------------------*/
2334 geniCodeUnaryMinus (operand * op)
2337 sym_link *optype = operandType (op);
2339 if (IS_LITERAL (optype))
2340 return operandFromLit (-floatFromVal (op->operand.valOperand));
2342 ic = newiCode (UNARYMINUS, op, NULL);
2343 IC_RESULT (ic) = newiTempOperand (optype, 0);
2345 return IC_RESULT (ic);
2348 /*-----------------------------------------------------------------*/
2349 /* geniCodeLeftShift - gen i code for left shift */
2350 /*-----------------------------------------------------------------*/
2352 geniCodeLeftShift (operand * left, operand * right)
2356 ic = newiCode (LEFT_OP, left, right);
2357 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2359 return IC_RESULT (ic);
2362 /*-----------------------------------------------------------------*/
2363 /* geniCodeRightShift - gen i code for right shift */
2364 /*-----------------------------------------------------------------*/
2366 geniCodeRightShift (operand * left, operand * right)
2370 ic = newiCode (RIGHT_OP, left, right);
2371 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2373 return IC_RESULT (ic);
2376 #if defined(__BORLANDC__) || defined(_MSC_VER)
2377 #define LONG_LONG __int64
2379 #define LONG_LONG long long
2382 /*-----------------------------------------------------------------*/
2383 /* geniCodeLogic- logic code */
2384 /*-----------------------------------------------------------------*/
2386 geniCodeLogic (operand * left, operand * right, int op)
2390 sym_link *rtype = operandType (right);
2391 sym_link *ltype = operandType (left);
2393 /* left is integral type and right is literal then
2394 check if the literal value is within bounds */
2395 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2397 int nbits = bitsForType (ltype);
2398 long v = (long) operandLitValue (right);
2400 if (v >= ((LONG_LONG) 1 << nbits) && v > 0)
2401 werror (W_CONST_RANGE, " compare operation ");
2404 ctype = usualBinaryConversions (&left, &right);
2406 ic = newiCode (op, left, right);
2407 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2409 /* if comparing float
2410 and not a '==' || '!=' || '&&' || '||' (these
2412 if (IS_FLOAT(ctype) &&
2420 return IC_RESULT (ic);
2423 /*-----------------------------------------------------------------*/
2424 /* geniCodeUnary - for a a generic unary operation */
2425 /*-----------------------------------------------------------------*/
2427 geniCodeUnary (operand * op, int oper)
2429 iCode *ic = newiCode (oper, op, NULL);
2431 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2433 return IC_RESULT (ic);
2436 /*-----------------------------------------------------------------*/
2437 /* geniCodeConditional - geniCode for '?' ':' operation */
2438 /*-----------------------------------------------------------------*/
2440 geniCodeConditional (ast * tree,int lvl)
2443 symbol *falseLabel = newiTempLabel (NULL);
2444 symbol *exitLabel = newiTempLabel (NULL);
2445 operand *cond = ast2iCode (tree->left,lvl+1);
2446 operand *true, *false, *result;
2448 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2452 true = ast2iCode (tree->right->left,lvl+1);
2454 /* move the value to a new Operand */
2455 result = newiTempOperand (operandType (true), 0);
2456 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2458 /* generate an unconditional goto */
2459 geniCodeGoto (exitLabel);
2461 /* now for the right side */
2462 geniCodeLabel (falseLabel);
2464 false = ast2iCode (tree->right->right,lvl+1);
2465 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2467 /* create the exit label */
2468 geniCodeLabel (exitLabel);
2473 /*-----------------------------------------------------------------*/
2474 /* geniCodeAssign - generate code for assignment */
2475 /*-----------------------------------------------------------------*/
2477 geniCodeAssign (operand * left, operand * right, int nosupdate)
2480 sym_link *ltype = operandType (left);
2481 sym_link *rtype = operandType (right);
2483 if (!left->isaddr && !IS_ITEMP (left))
2485 werror (E_LVALUE_REQUIRED, "assignment");
2489 /* left is integral type and right is literal then
2490 check if the literal value is within bounds */
2491 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2493 int nbits = bitsForType (ltype);
2494 long v = (long) operandLitValue (right);
2496 if (v >= ((LONG_LONG) 1 << nbits) && v > 0)
2497 werror (W_CONST_RANGE, " = operation");
2500 /* if the left & right type don't exactly match */
2501 /* if pointer set then make sure the check is
2502 done with the type & not the pointer */
2503 /* then cast rights type to left */
2505 /* first check the type for pointer assignement */
2506 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2507 compareType (ltype, rtype) < 0)
2509 if (compareType (ltype->next, rtype) < 0)
2510 right = geniCodeCast (ltype->next, right, TRUE);
2512 else if (compareType (ltype, rtype) < 0)
2513 right = geniCodeCast (ltype, right, TRUE);
2515 /* if left is a true symbol & ! volatile
2516 create an assignment to temporary for
2517 the right & then assign this temporary
2518 to the symbol this is SSA . isn't it simple
2519 and folks have published mountains of paper on it */
2520 if (IS_TRUE_SYMOP (left) &&
2521 !isOperandVolatile (left, FALSE) &&
2522 isOperandGlobal (left))
2526 if (IS_TRUE_SYMOP (right))
2527 sym = OP_SYMBOL (right);
2528 ic = newiCode ('=', NULL, right);
2529 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2530 SPIL_LOC (right) = sym;
2534 ic = newiCode ('=', NULL, right);
2535 IC_RESULT (ic) = left;
2538 /* if left isgptr flag is set then support
2539 routine will be required */
2543 ic->nosupdate = nosupdate;
2547 /*-----------------------------------------------------------------*/
2548 /* geniCodeSEParms - generate code for side effecting fcalls */
2549 /*-----------------------------------------------------------------*/
2551 geniCodeSEParms (ast * parms,int lvl)
2556 if (parms->type == EX_OP && parms->opval.op == PARAM)
2558 geniCodeSEParms (parms->left,lvl);
2559 geniCodeSEParms (parms->right,lvl);
2563 /* hack don't like this but too lazy to think of
2565 if (IS_ADDRESS_OF_OP (parms))
2566 parms->left->lvalue = 1;
2568 if (IS_CAST_OP (parms) &&
2569 IS_PTR (parms->ftype) &&
2570 IS_ADDRESS_OF_OP (parms->right))
2571 parms->right->left->lvalue = 1;
2573 parms->opval.oprnd =
2574 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2576 parms->type = EX_OPERAND;
2579 /*-----------------------------------------------------------------*/
2580 /* geniCodeParms - generates parameters */
2581 /*-----------------------------------------------------------------*/
2583 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2591 /* if this is a param node then do the left & right */
2592 if (parms->type == EX_OP && parms->opval.op == PARAM)
2594 geniCodeParms (parms->left, stack, fetype, func,lvl);
2595 geniCodeParms (parms->right, stack, fetype, func,lvl);
2599 /* get the parameter value */
2600 if (parms->type == EX_OPERAND)
2601 pval = parms->opval.oprnd;
2604 /* maybe this else should go away ?? */
2605 /* hack don't like this but too lazy to think of
2607 if (IS_ADDRESS_OF_OP (parms))
2608 parms->left->lvalue = 1;
2610 if (IS_CAST_OP (parms) &&
2611 IS_PTR (parms->ftype) &&
2612 IS_ADDRESS_OF_OP (parms->right))
2613 parms->right->left->lvalue = 1;
2615 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2618 /* if register parm then make it a send */
2619 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2620 IS_REGPARM (parms->etype)) && !func->hasVargs)
2622 ic = newiCode (SEND, pval, NULL);
2627 /* now decide whether to push or assign */
2628 if (!(options.stackAuto || IS_RENT (fetype)))
2632 operand *top = operandFromSymbol (parms->argSym);
2633 geniCodeAssign (top, pval, 1);
2637 sym_link *p = operandType (pval);
2639 ic = newiCode (IPUSH, pval, NULL);
2641 /* update the stack adjustment */
2642 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2649 /*-----------------------------------------------------------------*/
2650 /* geniCodeCall - generates temp code for calling */
2651 /*-----------------------------------------------------------------*/
2653 geniCodeCall (operand * left, ast * parms,int lvl)
2657 sym_link *type, *etype;
2660 /* take care of parameters with side-effecting
2661 function calls in them, this is required to take care
2662 of overlaying function parameters */
2663 geniCodeSEParms (parms,lvl);
2665 /* first the parameters */
2666 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2668 /* now call : if symbol then pcall */
2669 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2670 ic = newiCode (PCALL, left, NULL);
2672 ic = newiCode (CALL, left, NULL);
2674 IC_ARGS (ic) = left->operand.symOperand->args;
2675 type = copyLinkChain (operandType (left)->next);
2676 etype = getSpec (type);
2677 SPEC_EXTR (etype) = 0;
2678 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2682 /* stack adjustment after call */
2683 ic->parmBytes = stack;
2688 /*-----------------------------------------------------------------*/
2689 /* geniCodeReceive - generate intermediate code for "receive" */
2690 /*-----------------------------------------------------------------*/
2692 geniCodeReceive (value * args)
2694 /* for all arguments that are passed in registers */
2698 if (IS_REGPARM (args->etype))
2700 operand *opr = operandFromValue (args);
2702 symbol *sym = OP_SYMBOL (opr);
2705 /* we will use it after all optimizations
2706 and before liveRange calculation */
2707 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2710 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2711 options.stackAuto == 0 &&
2717 opl = newiTempOperand (args->type, 0);
2719 sym->reqv->key = sym->key;
2720 OP_SYMBOL (sym->reqv)->key = sym->key;
2721 OP_SYMBOL (sym->reqv)->isreqv = 1;
2722 OP_SYMBOL (sym->reqv)->islocal = 0;
2723 SPIL_LOC (sym->reqv) = sym;
2727 ic = newiCode (RECEIVE, NULL, NULL);
2728 currFunc->recvSize = getSize (sym->etype);
2729 IC_RESULT (ic) = opr;
2737 /*-----------------------------------------------------------------*/
2738 /* geniCodeFunctionBody - create the function body */
2739 /*-----------------------------------------------------------------*/
2741 geniCodeFunctionBody (ast * tree,int lvl)
2748 /* reset the auto generation */
2754 func = ast2iCode (tree->left,lvl+1);
2755 fetype = getSpec (operandType (func));
2757 savelineno = lineno;
2758 lineno = OP_SYMBOL (func)->lineDef;
2759 /* create an entry label */
2760 geniCodeLabel (entryLabel);
2761 lineno = savelineno;
2763 /* create a proc icode */
2764 ic = newiCode (FUNCTION, func, NULL);
2765 /* if the function has parmas then */
2766 /* save the parameters information */
2767 ic->argLabel.args = tree->values.args;
2768 ic->lineno = OP_SYMBOL (func)->lineDef;
2772 /* for all parameters that are passed
2773 on registers add a "receive" */
2774 geniCodeReceive (tree->values.args);
2776 /* generate code for the body */
2777 ast2iCode (tree->right,lvl+1);
2779 /* create a label for return */
2780 geniCodeLabel (returnLabel);
2782 /* now generate the end proc */
2783 ic = newiCode (ENDFUNCTION, func, NULL);
2788 /*-----------------------------------------------------------------*/
2789 /* geniCodeReturn - gen icode for 'return' statement */
2790 /*-----------------------------------------------------------------*/
2792 geniCodeReturn (operand * op)
2796 /* if the operand is present force an rvalue */
2798 op = geniCodeRValue (op, FALSE);
2800 ic = newiCode (RETURN, op, NULL);
2804 /*-----------------------------------------------------------------*/
2805 /* geniCodeIfx - generates code for extended if statement */
2806 /*-----------------------------------------------------------------*/
2808 geniCodeIfx (ast * tree,int lvl)
2811 operand *condition = ast2iCode (tree->left,lvl+1);
2814 /* if condition is null then exit */
2818 condition = geniCodeRValue (condition, FALSE);
2820 cetype = getSpec (operandType (condition));
2821 /* if the condition is a literal */
2822 if (IS_LITERAL (cetype))
2824 if (floatFromVal (condition->operand.valOperand))
2826 if (tree->trueLabel)
2827 geniCodeGoto (tree->trueLabel);
2833 if (tree->falseLabel)
2834 geniCodeGoto (tree->falseLabel);
2841 if (tree->trueLabel)
2843 ic = newiCodeCondition (condition,
2848 if (tree->falseLabel)
2849 geniCodeGoto (tree->falseLabel);
2853 ic = newiCodeCondition (condition,
2860 ast2iCode (tree->right,lvl+1);
2863 /*-----------------------------------------------------------------*/
2864 /* geniCodeJumpTable - tries to create a jump table for switch */
2865 /*-----------------------------------------------------------------*/
2867 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2869 int min = 0, max = 0, t, cnt = 0;
2876 if (!tree || !caseVals)
2879 /* the criteria for creating a jump table is */
2880 /* all integer numbers between the maximum & minimum must */
2881 /* be present , the maximum value should not exceed 255 */
2882 min = max = (int) floatFromVal (vch = caseVals);
2883 sprintf (buffer, "_case_%d_%d",
2884 tree->values.switchVals.swNum,
2886 addSet (&labels, newiTempLabel (buffer));
2888 /* if there is only one case value then no need */
2889 if (!(vch = vch->next))
2894 if (((t = (int) floatFromVal (vch)) - max) != 1)
2896 sprintf (buffer, "_case_%d_%d",
2897 tree->values.switchVals.swNum,
2899 addSet (&labels, newiTempLabel (buffer));
2905 /* if the number of case statements <= 2 then */
2906 /* it is not economical to create the jump table */
2907 /* since two compares are needed for boundary conditions */
2908 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2911 if (tree->values.switchVals.swDefault)
2912 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2914 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2916 falseLabel = newiTempLabel (buffer);
2918 /* so we can create a jumptable */
2919 /* first we rule out the boundary conditions */
2920 /* if only optimization says so */
2921 if (!optimize.noJTabBoundary)
2923 sym_link *cetype = getSpec (operandType (cond));
2924 /* no need to check the lower bound if
2925 the condition is unsigned & minimum value is zero */
2926 if (!(min == 0 && SPEC_USIGN (cetype)))
2928 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2929 ic = newiCodeCondition (boundary, falseLabel, NULL);
2933 /* now for upper bounds */
2934 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
2935 ic = newiCodeCondition (boundary, falseLabel, NULL);
2939 /* if the min is not zero then we no make it zero */
2942 cond = geniCodeSubtract (cond, operandFromLit (min));
2943 setOperandType (cond, UCHARTYPE);
2946 /* now create the jumptable */
2947 ic = newiCode (JUMPTABLE, NULL, NULL);
2948 IC_JTCOND (ic) = cond;
2949 IC_JTLABELS (ic) = labels;
2954 /*-----------------------------------------------------------------*/
2955 /* geniCodeSwitch - changes a switch to a if statement */
2956 /*-----------------------------------------------------------------*/
2958 geniCodeSwitch (ast * tree,int lvl)
2961 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
2962 value *caseVals = tree->values.switchVals.swVals;
2963 symbol *trueLabel, *falseLabel;
2965 /* if we can make this a jump table */
2966 if (geniCodeJumpTable (cond, caseVals, tree))
2967 goto jumpTable; /* no need for the comparison */
2969 /* for the cases defined do */
2973 operand *compare = geniCodeLogic (cond,
2974 operandFromValue (caseVals),
2977 sprintf (buffer, "_case_%d_%d",
2978 tree->values.switchVals.swNum,
2979 (int) floatFromVal (caseVals));
2980 trueLabel = newiTempLabel (buffer);
2982 ic = newiCodeCondition (compare, trueLabel, NULL);
2984 caseVals = caseVals->next;
2989 /* if default is present then goto break else break */
2990 if (tree->values.switchVals.swDefault)
2991 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2993 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2995 falseLabel = newiTempLabel (buffer);
2996 geniCodeGoto (falseLabel);
2999 ast2iCode (tree->right,lvl+1);
3002 /*-----------------------------------------------------------------*/
3003 /* geniCodeInline - intermediate code for inline assembler */
3004 /*-----------------------------------------------------------------*/
3006 geniCodeInline (ast * tree)
3010 ic = newiCode (INLINEASM, NULL, NULL);
3011 IC_INLINE (ic) = tree->values.inlineasm;
3015 /*-----------------------------------------------------------------*/
3016 /* geniCodeArrayInit - intermediate code for array initializer */
3017 /*-----------------------------------------------------------------*/
3019 geniCodeArrayInit (ast * tree, operand *array)
3023 ic = newiCode (ARRAYINIT, array, NULL);
3024 IC_ARRAYILIST (ic) = tree->values.constlist;
3028 /*-----------------------------------------------------------------*/
3029 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3030 /* particular case. Ie : assigning or dereferencing array or ptr */
3031 /*-----------------------------------------------------------------*/
3032 set * lvaluereqSet = NULL;
3033 typedef struct lvalItem
3040 /*-----------------------------------------------------------------*/
3041 /* addLvaluereq - add a flag for lvalreq for current ast level */
3042 /*-----------------------------------------------------------------*/
3043 void addLvaluereq(int lvl)
3045 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3048 addSetHead(&lvaluereqSet,lpItem);
3051 /*-----------------------------------------------------------------*/
3052 /* delLvaluereq - del a flag for lvalreq for current ast level */
3053 /*-----------------------------------------------------------------*/
3057 lpItem = getSet(&lvaluereqSet);
3058 if(lpItem) free(lpItem);
3060 /*-----------------------------------------------------------------*/
3061 /* clearLvaluereq - clear lvalreq flag */
3062 /*-----------------------------------------------------------------*/
3063 void clearLvaluereq()
3066 lpItem = peekSet(lvaluereqSet);
3067 if(lpItem) lpItem->req = 0;
3069 /*-----------------------------------------------------------------*/
3070 /* getLvaluereq - get the last lvalreq level */
3071 /*-----------------------------------------------------------------*/
3072 int getLvaluereqLvl()
3075 lpItem = peekSet(lvaluereqSet);
3076 if(lpItem) return lpItem->lvl;
3079 /*-----------------------------------------------------------------*/
3080 /* isLvaluereq - is lvalreq valid for this level ? */
3081 /*-----------------------------------------------------------------*/
3082 int isLvaluereq(int lvl)
3085 lpItem = peekSet(lvaluereqSet);
3086 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3090 /*-----------------------------------------------------------------*/
3091 /* ast2iCode - creates an icodeList from an ast */
3092 /*-----------------------------------------------------------------*/
3094 ast2iCode (ast * tree,int lvl)
3096 operand *left = NULL;
3097 operand *right = NULL;
3100 /* set the global variables for filename & line number */
3102 filename = tree->filename;
3104 lineno = tree->lineno;
3106 block = tree->block;
3108 scopeLevel = tree->level;
3110 if (tree->type == EX_VALUE)
3111 return operandFromValue (tree->opval.val);
3113 if (tree->type == EX_LINK)
3114 return operandFromLink (tree->opval.lnk);
3116 /* if we find a nullop */
3117 if (tree->type == EX_OP &&
3118 (tree->opval.op == NULLOP ||
3119 tree->opval.op == BLOCK))
3121 ast2iCode (tree->left,lvl+1);
3122 ast2iCode (tree->right,lvl+1);
3126 /* special cases for not evaluating */
3127 if (tree->opval.op != ':' &&
3128 tree->opval.op != '?' &&
3129 tree->opval.op != CALL &&
3130 tree->opval.op != IFX &&
3131 tree->opval.op != LABEL &&
3132 tree->opval.op != GOTO &&
3133 tree->opval.op != SWITCH &&
3134 tree->opval.op != FUNCTION &&
3135 tree->opval.op != INLINEASM)
3138 if (IS_ASSIGN_OP (tree->opval.op) ||
3139 IS_DEREF_OP (tree) ||
3140 (tree->opval.op == '&' && !tree->right) ||
3141 tree->opval.op == PTR_OP)
3144 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3145 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3148 left = operandFromAst (tree->left,lvl);
3150 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3151 left = geniCodeRValue (left, TRUE);
3155 left = operandFromAst (tree->left,lvl);
3157 if (tree->opval.op == INC_OP ||
3158 tree->opval.op == DEC_OP)
3161 right = operandFromAst (tree->right,lvl);
3166 right = operandFromAst (tree->right,lvl);
3170 /* now depending on the type of operand */
3171 /* this will be a biggy */
3172 switch (tree->opval.op)
3175 case '[': /* array operation */
3177 sym_link *ltype = operandType (left);
3178 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3179 right = geniCodeRValue (right, TRUE);
3182 return geniCodeArray (left, right,lvl);
3184 case '.': /* structure dereference */
3185 if (IS_PTR (operandType (left)))
3186 left = geniCodeRValue (left, TRUE);
3188 left = geniCodeRValue (left, FALSE);
3190 return geniCodeStruct (left, right, tree->lvalue);
3192 case PTR_OP: /* structure pointer dereference */
3195 pType = operandType (left);
3196 left = geniCodeRValue (left, TRUE);
3198 setOClass (pType, getSpec (operandType (left)));
3201 return geniCodeStruct (left, right, tree->lvalue);
3203 case INC_OP: /* increment operator */
3205 return geniCodePostInc (left);
3207 return geniCodePreInc (right);
3209 case DEC_OP: /* decrement operator */
3211 return geniCodePostDec (left);
3213 return geniCodePreDec (right);
3215 case '&': /* bitwise and or address of operator */
3217 { /* this is a bitwise operator */
3218 left = geniCodeRValue (left, FALSE);
3219 right = geniCodeRValue (right, FALSE);
3220 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3223 return geniCodeAddressOf (left);
3225 case '|': /* bitwise or & xor */
3227 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3228 geniCodeRValue (right, FALSE),
3233 return geniCodeDivision (geniCodeRValue (left, FALSE),
3234 geniCodeRValue (right, FALSE));
3237 return geniCodeModulus (geniCodeRValue (left, FALSE),
3238 geniCodeRValue (right, FALSE));
3241 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3242 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3244 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3248 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3249 geniCodeRValue (right, FALSE));
3251 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3255 return geniCodeAdd (geniCodeRValue (left, FALSE),
3256 geniCodeRValue (right, FALSE),lvl);
3258 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3261 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3262 geniCodeRValue (right, FALSE));
3265 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3266 geniCodeRValue (right, FALSE));
3268 return geniCodeCast (operandType (left),
3269 geniCodeRValue (right, FALSE), FALSE);
3275 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3279 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3280 setOperandType (op, UCHARTYPE);
3291 return geniCodeLogic (geniCodeRValue (left, FALSE),
3292 geniCodeRValue (right, FALSE),
3295 return geniCodeConditional (tree,lvl);
3298 return operandFromLit (getSize (tree->right->ftype));
3302 sym_link *rtype = operandType (right);
3303 sym_link *ltype = operandType (left);
3304 if (IS_PTR (rtype) && IS_ITEMP (right)
3305 && right->isaddr && compareType (rtype->next, ltype) == 1)
3306 right = geniCodeRValue (right, TRUE);
3308 right = geniCodeRValue (right, FALSE);
3310 geniCodeAssign (left, right, 0);
3315 geniCodeAssign (left,
3316 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3318 geniCodeRValue (right, FALSE),FALSE), 0);
3322 geniCodeAssign (left,
3323 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3325 geniCodeRValue (right, FALSE)), 0);
3328 geniCodeAssign (left,
3329 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3331 geniCodeRValue (right, FALSE)), 0);
3334 sym_link *rtype = operandType (right);
3335 sym_link *ltype = operandType (left);
3336 if (IS_PTR (rtype) && IS_ITEMP (right)
3337 && right->isaddr && compareType (rtype->next, ltype) == 1)
3338 right = geniCodeRValue (right, TRUE);
3340 right = geniCodeRValue (right, FALSE);
3343 return geniCodeAssign (left,
3344 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3350 sym_link *rtype = operandType (right);
3351 sym_link *ltype = operandType (left);
3352 if (IS_PTR (rtype) && IS_ITEMP (right)
3353 && right->isaddr && compareType (rtype->next, ltype) == 1)
3355 right = geniCodeRValue (right, TRUE);
3359 right = geniCodeRValue (right, FALSE);
3362 geniCodeAssign (left,
3363 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3369 geniCodeAssign (left,
3370 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3372 geniCodeRValue (right, FALSE)), 0);
3375 geniCodeAssign (left,
3376 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3378 geniCodeRValue (right, FALSE)), 0);
3381 geniCodeAssign (left,
3382 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3384 geniCodeRValue (right, FALSE),
3386 operandType (left)), 0);
3389 geniCodeAssign (left,
3390 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3392 geniCodeRValue (right, FALSE),
3394 operandType (left)), 0);
3397 geniCodeAssign (left,
3398 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3400 geniCodeRValue (right, FALSE),
3402 operandType (left)), 0);
3404 return geniCodeRValue (right, FALSE);
3407 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3410 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3411 return ast2iCode (tree->right,lvl+1);
3414 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3415 return ast2iCode (tree->right,lvl+1);
3418 geniCodeFunctionBody (tree,lvl);
3422 geniCodeReturn (right);
3426 geniCodeIfx (tree,lvl);
3430 geniCodeSwitch (tree,lvl);
3434 geniCodeInline (tree);
3438 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3445 /*-----------------------------------------------------------------*/
3446 /* reverseICChain - gets from the list and creates a linkedlist */
3447 /*-----------------------------------------------------------------*/
3454 while ((loop = getSet (&iCodeChain)))
3466 /*-----------------------------------------------------------------*/
3467 /* iCodeFromAst - given an ast will convert it to iCode */
3468 /*-----------------------------------------------------------------*/
3470 iCodeFromAst (ast * tree)
3472 returnLabel = newiTempLabel ("_return");
3473 entryLabel = newiTempLabel ("_entry");
3475 return reverseiCChain ();