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);
52 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
53 /* forward definition of ic print functions */
54 PRINTFUNC (picGetValueAtAddr);
55 PRINTFUNC (picSetValueAtAddr);
56 PRINTFUNC (picAddrOf);
57 PRINTFUNC (picGeneric);
58 PRINTFUNC (picGenericOne);
60 PRINTFUNC (picAssign);
64 PRINTFUNC (picJumpTable);
65 PRINTFUNC (picInline);
66 PRINTFUNC (picReceive);
68 iCodeTable codeTable[] =
70 {'!', "not", picGenericOne, NULL},
71 {'~', "~", picGenericOne, NULL},
72 {RRC, "rrc", picGenericOne, NULL},
73 {RLC, "rlc", picGenericOne, NULL},
74 {GETHBIT, "ghbit", picGenericOne, NULL},
75 {UNARYMINUS, "-", picGenericOne, NULL},
76 {IPUSH, "push", picGenericOne, NULL},
77 {IPOP, "pop", picGenericOne, NULL},
78 {CALL, "call", picGenericOne, NULL},
79 {PCALL, "pcall", picGenericOne, NULL},
80 {FUNCTION, "proc", picGenericOne, NULL},
81 {ENDFUNCTION, "eproc", picGenericOne, NULL},
82 {RETURN, "ret", picGenericOne, NULL},
83 {'+', "+", picGeneric, NULL},
84 {'-', "-", picGeneric, NULL},
85 {'*', "*", picGeneric, NULL},
86 {'/', "/", picGeneric, NULL},
87 {'%', "%", picGeneric, NULL},
88 {'>', ">", picGeneric, NULL},
89 {'<', "<", picGeneric, NULL},
90 {LE_OP, "<=", picGeneric, NULL},
91 {GE_OP, ">=", picGeneric, NULL},
92 {EQ_OP, "==", picGeneric, NULL},
93 {NE_OP, "!=", picGeneric, NULL},
94 {AND_OP, "&&", picGeneric, NULL},
95 {OR_OP, "||", picGeneric, NULL},
96 {'^', "^", picGeneric, NULL},
97 {'|', "|", picGeneric, NULL},
98 {BITWISEAND, "&", picGeneric, NULL},
99 {LEFT_OP, "<<", picGeneric, NULL},
100 {RIGHT_OP, ">>", picGeneric, NULL},
101 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
102 {ADDRESS_OF, "&", picAddrOf, NULL},
103 {CAST, "<>", picCast, NULL},
104 {'=', ":=", picAssign, NULL},
105 {LABEL, "", picLabel, NULL},
106 {GOTO, "", picGoto, NULL},
107 {JUMPTABLE, "jtab", picJumpTable, NULL},
108 {IFX, "if", picIfx, NULL},
109 {INLINEASM, "", picInline, NULL},
110 {RECEIVE, "recv", picReceive, NULL},
111 {SEND, "send", picGenericOne, NULL}
115 /*-----------------------------------------------------------------*/
116 /* operandName - returns the name of the operand */
117 /*-----------------------------------------------------------------*/
119 printOperand (operand * op, FILE * file)
136 opetype = getSpec (operandType (op));
137 if (SPEC_NOUN (opetype) == V_FLOAT)
138 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
140 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
141 printTypeChain (operandType (op), file);
148 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
149 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
151 OP_LIVEFROM (op), OP_LIVETO (op),
152 OP_SYMBOL (op)->stack,
153 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat
157 printTypeChain (operandType (op), file);
158 if (SPIL_LOC (op) && IS_ITEMP (op))
159 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
164 /* if assigned to registers */
165 if (OP_SYMBOL (op)->nRegs)
167 if (OP_SYMBOL (op)->isspilt)
169 if (!OP_SYMBOL (op)->remat)
170 if (OP_SYMBOL (op)->usl.spillLoc)
171 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
172 OP_SYMBOL (op)->usl.spillLoc->rname :
173 OP_SYMBOL (op)->usl.spillLoc->name));
175 fprintf (file, "[err]");
177 fprintf (file, "[remat]");
183 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
184 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
189 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
190 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
191 /* if assigned to registers */
192 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
196 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
197 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
198 OP_SYMBOL (op)->regs[i]->name :
207 printTypeChain (op->operand.typeOperand, file);
213 fprintf (file, "\n");
218 /*-----------------------------------------------------------------*/
219 /* print functions */
220 /*-----------------------------------------------------------------*/
221 PRINTFUNC (picGetValueAtAddr)
224 printOperand (IC_RESULT (ic), of);
227 printOperand (IC_LEFT (ic), of);
233 PRINTFUNC (picSetValueAtAddr)
237 printOperand (IC_LEFT (ic), of);
238 fprintf (of, "] = ");
239 printOperand (IC_RIGHT (ic), of);
243 PRINTFUNC (picAddrOf)
246 printOperand (IC_RESULT (ic), of);
247 if (IS_ITEMP (IC_LEFT (ic)))
250 fprintf (of, " = &[");
251 printOperand (IC_LEFT (ic), of);
254 if (IS_ITEMP (IC_LEFT (ic)))
255 fprintf (of, " offsetAdd ");
258 printOperand (IC_RIGHT (ic), of);
260 if (IS_ITEMP (IC_LEFT (ic)))
266 PRINTFUNC (picJumpTable)
271 fprintf (of, "%s\t", s);
272 printOperand (IC_JTCOND (ic), of);
274 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
275 sym = setNextItem (IC_JTLABELS (ic)))
276 fprintf (of, "\t\t\t%s\n", sym->name);
279 PRINTFUNC (picGeneric)
282 printOperand (IC_RESULT (ic), of);
284 printOperand (IC_LEFT (ic), of);
285 fprintf (of, " %s ", s);
286 printOperand (IC_RIGHT (ic), of);
290 PRINTFUNC (picGenericOne)
295 printOperand (IC_RESULT (ic), of);
301 fprintf (of, "%s ", s);
302 printOperand (IC_LEFT (ic), of);
305 if (!IC_RESULT (ic) && !IC_LEFT (ic))
314 printOperand (IC_RESULT (ic), of);
316 printOperand (IC_LEFT (ic), of);
317 printOperand (IC_RIGHT (ic), of);
322 PRINTFUNC (picAssign)
326 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
329 printOperand (IC_RESULT (ic), of);
331 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
334 fprintf (of, " %s ", s);
335 printOperand (IC_RIGHT (ic), of);
342 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
348 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
355 printOperand (IC_COND (ic), of);
358 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
361 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
363 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
367 PRINTFUNC (picInline)
369 fprintf (of, "%s", IC_INLINE (ic));
372 PRINTFUNC (picReceive)
374 printOperand (IC_RESULT (ic), of);
375 fprintf (of, " = %s ", s);
376 printOperand (IC_LEFT (ic), of);
380 /*-----------------------------------------------------------------*/
381 /* piCode - prints one iCode */
382 /*-----------------------------------------------------------------*/
384 piCode (void *item, FILE * of)
392 icTab = getTableEntry (ic->op);
393 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
394 ic->filename, ic->lineno,
395 ic->seq, ic->key, ic->depth, ic->supportRtn);
396 icTab->iCodePrint (of, ic, icTab->printName);
402 printiCChain(ic,stdout);
404 /*-----------------------------------------------------------------*/
405 /* printiCChain - prints intermediate code for humans */
406 /*-----------------------------------------------------------------*/
408 printiCChain (iCode * icChain, FILE * of)
415 for (loop = icChain; loop; loop = loop->next)
417 if ((icTab = getTableEntry (loop->op)))
419 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
420 loop->filename, loop->lineno,
421 loop->seq, loop->key, loop->depth, loop->supportRtn);
423 icTab->iCodePrint (of, loop, icTab->printName);
429 /*-----------------------------------------------------------------*/
430 /* newOperand - allocate, init & return a new iCode */
431 /*-----------------------------------------------------------------*/
437 op = Safe_calloc (1, sizeof (operand));
443 /*-----------------------------------------------------------------*/
444 /* newiCode - create and return a new iCode entry initialised */
445 /*-----------------------------------------------------------------*/
447 newiCode (int op, operand * left, operand * right)
451 ic = Safe_calloc (1, sizeof (iCode));
454 ic->filename = filename;
456 ic->level = scopeLevel;
458 ic->key = iCodeKey++;
460 IC_RIGHT (ic) = right;
465 /*-----------------------------------------------------------------*/
466 /* newiCode for conditional statements */
467 /*-----------------------------------------------------------------*/
469 newiCodeCondition (operand * condition,
475 ic = newiCode (IFX, NULL, NULL);
476 IC_COND (ic) = condition;
477 IC_TRUE (ic) = trueLabel;
478 IC_FALSE (ic) = falseLabel;
482 /*-----------------------------------------------------------------*/
483 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
484 /*-----------------------------------------------------------------*/
486 newiCodeLabelGoto (int op, symbol * label)
490 ic = newiCode (op, NULL, NULL);
492 ic->argLabel.label = label;
494 IC_RIGHT (ic) = NULL;
495 IC_RESULT (ic) = NULL;
499 /*-----------------------------------------------------------------*/
500 /* newiTemp - allocate & return a newItemp Variable */
501 /*-----------------------------------------------------------------*/
508 sprintf (buffer, "%s", s);
510 sprintf (buffer, "iTemp%d", iTempNum++);
511 itmp = newSymbol (buffer, 1);
512 strcpy (itmp->rname, itmp->name);
518 /*-----------------------------------------------------------------*/
519 /* newiTempLabel - creates a temp variable label */
520 /*-----------------------------------------------------------------*/
522 newiTempLabel (char *s)
526 /* check if this alredy exists */
527 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
531 itmplbl = newSymbol (s, 1);
534 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
535 itmplbl = newSymbol (buffer, 1);
540 itmplbl->key = labelKey++;
541 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
545 /*-----------------------------------------------------------------*/
546 /* newiTempPreheaderLabel - creates a new preheader label */
547 /*-----------------------------------------------------------------*/
549 newiTempPreheaderLabel ()
553 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
554 itmplbl = newSymbol (buffer, 1);
558 itmplbl->key = labelKey++;
559 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
564 /*-----------------------------------------------------------------*/
565 /* initiCode - initialises some iCode related stuff */
566 /*-----------------------------------------------------------------*/
573 /*-----------------------------------------------------------------*/
574 /* copyiCode - make a copy of the iCode given */
575 /*-----------------------------------------------------------------*/
577 copyiCode (iCode * ic)
579 iCode *nic = newiCode (ic->op, NULL, NULL);
581 nic->lineno = ic->lineno;
582 nic->filename = ic->filename;
583 nic->block = ic->block;
584 nic->level = ic->level;
585 nic->parmBytes = ic->parmBytes;
587 /* deal with the special cases first */
591 IC_COND (nic) = operandFromOperand (IC_COND (ic));
592 IC_TRUE (nic) = IC_TRUE (ic);
593 IC_FALSE (nic) = IC_FALSE (ic);
597 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
598 IC_JTLABELS (nic) = IC_JTLABELS (ic);
603 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
604 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
605 IC_ARGS (nic) = IC_ARGS (ic);
609 IC_INLINE (nic) = IC_INLINE (ic);
613 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
614 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
615 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
621 /*-----------------------------------------------------------------*/
622 /* getTableEntry - gets the table entry for the given operator */
623 /*-----------------------------------------------------------------*/
625 getTableEntry (int oper)
629 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
630 if (oper == codeTable[i].icode)
631 return &codeTable[i];
636 /*-----------------------------------------------------------------*/
637 /* newiTempOperand - new intermediate temp operand */
638 /*-----------------------------------------------------------------*/
640 newiTempOperand (sym_link * type, char throwType)
643 operand *op = newOperand ();
647 itmp = newiTemp (NULL);
649 etype = getSpec (type);
651 if (IS_LITERAL (etype))
654 /* copy the type information */
656 itmp->etype = getSpec (itmp->type = (throwType ? type :
657 copyLinkChain (type)));
658 if (IS_LITERAL (itmp->etype))
660 SPEC_SCLS (itmp->etype) = S_REGISTER;
661 SPEC_OCLS (itmp->etype) = reg;
664 op->operand.symOperand = itmp;
665 op->key = itmp->key = ++operandKey;
669 /*-----------------------------------------------------------------*/
670 /* operandType - returns the type chain for an operand */
671 /*-----------------------------------------------------------------*/
673 operandType (operand * op)
675 /* depending on type of operand */
680 return op->operand.valOperand->type;
683 return op->operand.symOperand->type;
686 return op->operand.typeOperand;
688 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
689 " operand type not known ");
690 assert (0); /* should never come here */
691 /* Just to keep the compiler happy */
692 return (sym_link *) 0;
696 /*-----------------------------------------------------------------*/
697 /* isParamterToCall - will return 1 if op is a parameter to args */
698 /*-----------------------------------------------------------------*/
700 isParameterToCall (value * args, operand * op)
707 isSymbolEqual (op->operand.symOperand, tval->sym))
714 /*-----------------------------------------------------------------*/
715 /* isOperandGlobal - return 1 if operand is a global variable */
716 /*-----------------------------------------------------------------*/
718 isOperandGlobal (operand * op)
726 if (op->type == SYMBOL &&
727 (op->operand.symOperand->level == 0 ||
728 IS_STATIC (op->operand.symOperand->etype) ||
729 IS_EXTERN (op->operand.symOperand->etype))
736 /*-----------------------------------------------------------------*/
737 /* isOperandVolatile - return 1 if the operand is volatile */
738 /*-----------------------------------------------------------------*/
740 isOperandVolatile (operand * op, bool chkTemp)
745 if (IS_ITEMP (op) && !chkTemp)
748 opetype = getSpec (optype = operandType (op));
750 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
753 if (IS_VOLATILE (opetype))
758 /*-----------------------------------------------------------------*/
759 /* isOperandLiteral - returns 1 if an operand contains a literal */
760 /*-----------------------------------------------------------------*/
762 isOperandLiteral (operand * op)
769 opetype = getSpec (operandType (op));
771 if (IS_LITERAL (opetype))
776 /*-----------------------------------------------------------------*/
777 /* isOperandInFarSpace - will return true if operand is in farSpace */
778 /*-----------------------------------------------------------------*/
780 isOperandInFarSpace (operand * op)
790 if (!IS_TRUE_SYMOP (op))
793 etype = SPIL_LOC (op)->etype;
799 etype = getSpec (operandType (op));
801 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
804 /*-----------------------------------------------------------------*/
805 /* isOperandOnStack - will return true if operand is on stack */
806 /*-----------------------------------------------------------------*/
808 isOperandOnStack (operand * op)
818 etype = getSpec (operandType (op));
820 return ((IN_STACK (etype)) ? TRUE : FALSE);
823 /*-----------------------------------------------------------------*/
824 /* operandLitValue - literal value of an operand */
825 /*-----------------------------------------------------------------*/
827 operandLitValue (operand * op)
829 assert (isOperandLiteral (op));
831 return floatFromVal (op->operand.valOperand);
834 /*-----------------------------------------------------------------*/
835 /* operandOperation - perforoms operations on operands */
836 /*-----------------------------------------------------------------*/
838 operandOperation (operand * left, operand * right,
839 int op, sym_link * type)
841 sym_link *let , *ret;
842 operand *retval = (operand *) 0;
844 assert (isOperandLiteral (left));
845 let = getSpec(operandType(left));
847 assert (isOperandLiteral (right));
848 ret = getSpec(operandType(left));
854 retval = operandFromValue (valCastLiteral (type,
855 operandLitValue (left) +
856 operandLitValue (right)));
859 retval = operandFromValue (valCastLiteral (type,
860 operandLitValue (left) -
861 operandLitValue (right)));
864 retval = operandFromValue (valCastLiteral (type,
865 operandLitValue (left) *
866 operandLitValue (right)));
869 if ((unsigned long) operandLitValue (right) == 0)
871 werror (E_DIVIDE_BY_ZERO);
876 retval = operandFromValue (valCastLiteral (type,
877 operandLitValue (left) /
878 operandLitValue (right)));
881 if ((unsigned long) operandLitValue (right) == 0) {
882 werror (E_DIVIDE_BY_ZERO);
886 retval = operandFromLit ((SPEC_USIGN(let) ?
887 (unsigned long) operandLitValue (left) :
888 (long) operandLitValue (left)) %
890 (unsigned long) operandLitValue (right) :
891 (long) operandLitValue (right)));
895 retval = operandFromLit (((SPEC_USIGN(let) ?
896 (unsigned long) operandLitValue (left) :
897 (long) operandLitValue (left)) <<
899 (unsigned long) operandLitValue (right) :
900 (long) operandLitValue (right))));
903 retval = operandFromLit (((SPEC_USIGN(let) ?
904 (unsigned long) operandLitValue (left) :
905 (long) operandLitValue (left)) >>
907 (unsigned long) operandLitValue (right) :
908 (long) operandLitValue (right))));
911 retval = operandFromLit (operandLitValue (left) ==
912 operandLitValue (right));
915 retval = operandFromLit (operandLitValue (left) <
916 operandLitValue (right));
919 retval = operandFromLit (operandLitValue (left) <=
920 operandLitValue (right));
923 retval = operandFromLit (operandLitValue (left) !=
924 operandLitValue (right));
927 retval = operandFromLit (operandLitValue (left) >
928 operandLitValue (right));
931 retval = operandFromLit (operandLitValue (left) >=
932 operandLitValue (right));
935 retval = operandFromLit ((unsigned long) operandLitValue (left) &
936 (unsigned long) operandLitValue (right));
939 retval = operandFromLit ((unsigned long) operandLitValue (left) |
940 (unsigned long) operandLitValue (right));
943 retval = operandFromLit ((unsigned long) operandLitValue (left) ^
944 (unsigned long) operandLitValue (right));
947 retval = operandFromLit (operandLitValue (left) &&
948 operandLitValue (right));
951 retval = operandFromLit (operandLitValue (left) ||
952 operandLitValue (right));
956 long i = operandLitValue (left);
958 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
964 long i = operandLitValue (left);
966 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
972 retval = operandFromLit (-1 * operandLitValue (left));
976 retval = operandFromLit (~((long) operandLitValue (left)));
980 retval = operandFromLit (!operandLitValue (left));
984 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
985 " operandOperation invalid operator ");
993 /*-----------------------------------------------------------------*/
994 /* isOperandEqual - compares two operand & return 1 if they r = */
995 /*-----------------------------------------------------------------*/
997 isOperandEqual (operand * left, operand * right)
999 /* if the pointers are equal then they are equal */
1003 /* if either of them null then false */
1004 if (!left || !right)
1007 if (left->type != right->type)
1010 if (IS_SYMOP (left) && IS_SYMOP (right))
1011 return left->key == right->key;
1013 /* if types are the same */
1017 return isSymbolEqual (left->operand.symOperand,
1018 right->operand.symOperand);
1020 return (floatFromVal (left->operand.valOperand) ==
1021 floatFromVal (right->operand.valOperand));
1023 if (checkType (left->operand.typeOperand,
1024 right->operand.typeOperand) == 1)
1031 /*-----------------------------------------------------------------*/
1032 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1033 /*-----------------------------------------------------------------*/
1035 isiCodeEqual (iCode * left, iCode * right)
1037 /* if the same pointer */
1041 /* if either of them null */
1042 if (!left || !right)
1045 /* if operand are the same */
1046 if (left->op == right->op)
1049 /* compare all the elements depending on type */
1050 if (left->op != IFX)
1052 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1054 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1060 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1062 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1064 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1072 /*-----------------------------------------------------------------*/
1073 /* newiTempFromOp - create a temp Operand with same attributes */
1074 /*-----------------------------------------------------------------*/
1076 newiTempFromOp (operand * op)
1086 nop = newiTempOperand (operandType (op), TRUE);
1087 nop->isaddr = op->isaddr;
1088 nop->isvolatile = op->isvolatile;
1089 nop->isGlobal = op->isGlobal;
1090 nop->isLiteral = op->isLiteral;
1091 nop->noSpilLoc = op->noSpilLoc;
1092 nop->usesDefs = op->usesDefs;
1093 nop->isParm = op->isParm;
1097 /*-----------------------------------------------------------------*/
1098 /* operand from operand - creates an operand holder for the type */
1099 /*-----------------------------------------------------------------*/
1101 operandFromOperand (operand * op)
1107 nop = newOperand ();
1108 nop->type = op->type;
1109 nop->isaddr = op->isaddr;
1111 nop->isvolatile = op->isvolatile;
1112 nop->isGlobal = op->isGlobal;
1113 nop->isLiteral = op->isLiteral;
1114 nop->noSpilLoc = op->noSpilLoc;
1115 nop->usesDefs = op->usesDefs;
1116 nop->isParm = op->isParm;
1121 nop->operand.symOperand = op->operand.symOperand;
1124 nop->operand.valOperand = op->operand.valOperand;
1127 nop->operand.typeOperand = op->operand.typeOperand;
1134 /*-----------------------------------------------------------------*/
1135 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1136 /*-----------------------------------------------------------------*/
1138 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1140 operand *nop = operandFromOperand (op);
1142 if (nop->type == SYMBOL)
1144 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1145 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1151 /*-----------------------------------------------------------------*/
1152 /* operandFromSymbol - creates an operand from a symbol */
1153 /*-----------------------------------------------------------------*/
1155 operandFromSymbol (symbol * sym)
1160 /* if the symbol's type is a literal */
1161 /* then it is an enumerator type */
1162 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1163 return operandFromValue (valFromType (sym->etype));
1166 sym->key = ++operandKey;
1168 /* if this an implicit variable, means struct/union */
1169 /* member so just return it */
1170 if (sym->implicit || IS_FUNC (sym->type))
1174 op->operand.symOperand = sym;
1176 op->isvolatile = isOperandVolatile (op, TRUE);
1177 op->isGlobal = isOperandGlobal (op);
1181 /* under the following conditions create a
1182 register equivalent for a local symbol */
1183 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1184 (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) &&
1185 options.stackAuto == 0)
1188 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1189 !IS_FUNC (sym->type) && /* not a function */
1190 !sym->_isparm && /* not a parameter */
1191 sym->level && /* is a local variable */
1192 !sym->addrtaken && /* whose address has not been taken */
1193 !sym->reqv && /* does not already have a register euivalence */
1194 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1195 !IS_STATIC (sym->etype) && /* and not declared static */
1196 !sym->islbl && /* not a label */
1197 ok && /* farspace check */
1198 !IS_BITVAR (sym->etype) /* not a bit variable */
1202 /* we will use it after all optimizations
1203 and before liveRange calculation */
1204 sym->reqv = newiTempOperand (sym->type, 0);
1205 sym->reqv->key = sym->key;
1206 OP_SYMBOL (sym->reqv)->key = sym->key;
1207 OP_SYMBOL (sym->reqv)->isreqv = 1;
1208 OP_SYMBOL (sym->reqv)->islocal = 1;
1209 SPIL_LOC (sym->reqv) = sym;
1212 if (!IS_AGGREGATE (sym->type))
1216 op->operand.symOperand = sym;
1219 op->isvolatile = isOperandVolatile (op, TRUE);
1220 op->isGlobal = isOperandGlobal (op);
1221 op->isPtr = IS_PTR (operandType (op));
1222 op->isParm = sym->_isparm;
1227 /* itemp = &[_symbol] */
1229 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1230 IC_LEFT (ic)->type = SYMBOL;
1231 IC_LEFT (ic)->operand.symOperand = sym;
1232 IC_LEFT (ic)->key = sym->key;
1233 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1234 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1235 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1238 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1239 if (IS_ARRAY (sym->type))
1241 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1242 IC_RESULT (ic)->isaddr = 0;
1245 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1247 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1251 return IC_RESULT (ic);
1254 /*-----------------------------------------------------------------*/
1255 /* operandFromValue - creates an operand from value */
1256 /*-----------------------------------------------------------------*/
1258 operandFromValue (value * val)
1262 /* if this is a symbol then do the symbol thing */
1264 return operandFromSymbol (val->sym);
1266 /* this is not a symbol */
1269 op->operand.valOperand = val;
1270 op->isLiteral = isOperandLiteral (op);
1274 /*-----------------------------------------------------------------*/
1275 /* operandFromLink - operand from typeChain */
1276 /*-----------------------------------------------------------------*/
1278 operandFromLink (sym_link * type)
1282 /* operand from sym_link */
1288 op->operand.typeOperand = copyLinkChain (type);
1292 /*-----------------------------------------------------------------*/
1293 /* operandFromLit - makes an operand from a literal value */
1294 /*-----------------------------------------------------------------*/
1296 operandFromLit (float i)
1298 return operandFromValue (valueFromLit (i));
1301 /*-----------------------------------------------------------------*/
1302 /* operandFromAst - creates an operand from an ast */
1303 /*-----------------------------------------------------------------*/
1305 operandFromAst (ast * tree,int lvl)
1311 /* depending on type do */
1315 return ast2iCode (tree,lvl+1);
1319 return operandFromValue (tree->opval.val);
1323 return operandFromLink (tree->opval.lnk);
1327 /* Just to keep the comiler happy */
1328 return (operand *) 0;
1331 /*-----------------------------------------------------------------*/
1332 /* setOperandType - sets the operand's type to the given type */
1333 /*-----------------------------------------------------------------*/
1335 setOperandType (operand * op, sym_link * type)
1337 /* depending on the type of operand */
1342 op->operand.valOperand->etype =
1343 getSpec (op->operand.valOperand->type =
1344 copyLinkChain (type));
1348 if (op->operand.symOperand->isitmp)
1349 op->operand.symOperand->etype =
1350 getSpec (op->operand.symOperand->type =
1351 copyLinkChain (type));
1353 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1354 "attempt to modify type of source");
1358 op->operand.typeOperand = copyLinkChain (type);
1363 /*-----------------------------------------------------------------*/
1364 /* Get size in byte of ptr need to access an array */
1365 /*-----------------------------------------------------------------*/
1367 getArraySizePtr (operand * op)
1369 sym_link *ltype = operandType(op);
1373 int size = getSize(ltype);
1374 return(IS_GENPTR(ltype)?(size-1):size);
1379 sym_link *letype = getSpec(ltype);
1380 switch (PTR_TYPE (SPEC_OCLS (letype)))
1392 return (GPTRSIZE-1);
1401 /*-----------------------------------------------------------------*/
1402 /* perform "usual unary conversions" */
1403 /*-----------------------------------------------------------------*/
1405 usualUnaryConversions (operand * op)
1407 if (IS_INTEGRAL (operandType (op)))
1409 if (getSize (operandType (op)) < INTSIZE)
1412 return geniCodeCast (INTTYPE, op, TRUE);
1418 /*-----------------------------------------------------------------*/
1419 /* perform "usual binary conversions" */
1420 /*-----------------------------------------------------------------*/
1422 usualBinaryConversions (operand ** op1, operand ** op2)
1425 sym_link *rtype = operandType (*op2);
1426 sym_link *ltype = operandType (*op1);
1428 ctype = computeType (ltype, rtype);
1429 *op1 = geniCodeCast (ctype, *op1, TRUE);
1430 *op2 = geniCodeCast (ctype, *op2, TRUE);
1435 /*-----------------------------------------------------------------*/
1436 /* geniCodeValueAtAddress - generate intermeditate code for value */
1438 /*-----------------------------------------------------------------*/
1440 geniCodeRValue (operand * op, bool force)
1443 sym_link *type = operandType (op);
1444 sym_link *etype = getSpec (type);
1446 /* if this is an array & already */
1447 /* an address then return this */
1448 if (IS_AGGREGATE (type) ||
1449 (IS_PTR (type) && !force && !op->isaddr))
1450 return operandFromOperand (op);
1452 /* if this is not an address then must be */
1453 /* rvalue already so return this one */
1457 /* if this is not a temp symbol then */
1458 if (!IS_ITEMP (op) &&
1460 !IN_FARSPACE (SPEC_OCLS (etype)))
1462 op = operandFromOperand (op);
1467 if (IS_SPEC (type) &&
1468 IS_TRUE_SYMOP (op) &&
1469 (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
1471 op = operandFromOperand (op);
1476 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1477 if (IS_PTR (type) && op->isaddr && force)
1480 type = copyLinkChain (type);
1482 IC_RESULT (ic) = newiTempOperand (type, 1);
1483 IC_RESULT (ic)->isaddr = 0;
1485 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1487 /* if the right is a symbol */
1488 if (op->type == SYMBOL)
1489 IC_RESULT (ic)->operand.symOperand->args =
1490 op->operand.symOperand->args;
1493 return IC_RESULT (ic);
1496 /*-----------------------------------------------------------------*/
1497 /* geniCodeCast - changes the value from one type to another */
1498 /*-----------------------------------------------------------------*/
1500 geniCodeCast (sym_link * type, operand * op, bool implicit)
1504 sym_link *opetype = getSpec (optype = operandType (op));
1507 /* one of them has size zero then error */
1508 if (IS_VOID (optype))
1510 werror (E_CAST_ZERO);
1514 /* if the operand is already the desired type then do nothing */
1515 if (checkType (type, optype) == 1)
1518 /* if this is a literal then just change the type & return */
1519 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1520 return operandFromValue (valCastLiteral (type,
1521 operandLitValue (op)));
1523 /* if casting to some pointer type &&
1524 the destination is not a generic pointer
1525 then give a warning : (only for implicit casts) */
1526 if (IS_PTR (optype) && implicit &&
1527 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1530 werror (E_INCOMPAT_CAST);
1531 werror (E_CONTINUE, "from type '");
1532 printTypeChain (optype, stderr);
1533 fprintf (stderr, "' to type '");
1534 printTypeChain (type, stderr);
1535 fprintf (stderr, "'\n");
1538 /* if they are the same size create an assignment */
1539 if (getSize (type) == getSize (optype) &&
1540 !IS_BITFIELD (type) &&
1542 !IS_FLOAT (optype) &&
1543 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1544 (!IS_SPEC (type) && !IS_SPEC (optype))))
1547 ic = newiCode ('=', NULL, op);
1548 IC_RESULT (ic) = newiTempOperand (type, 0);
1549 SPIL_LOC (IC_RESULT (ic)) =
1550 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1551 IC_RESULT (ic)->isaddr = 0;
1555 ic = newiCode (CAST, operandFromLink (type),
1556 geniCodeRValue (op, FALSE));
1558 IC_RESULT (ic) = newiTempOperand (type, 0);
1561 /* preserve the storage class & output class */
1562 /* of the original variable */
1563 restype = getSpec (operandType (IC_RESULT (ic)));
1564 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1565 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1568 return IC_RESULT (ic);
1571 /*-----------------------------------------------------------------*/
1572 /* geniCodeLabel - will create a Label */
1573 /*-----------------------------------------------------------------*/
1575 geniCodeLabel (symbol * label)
1579 ic = newiCodeLabelGoto (LABEL, label);
1583 /*-----------------------------------------------------------------*/
1584 /* geniCodeGoto - will create a Goto */
1585 /*-----------------------------------------------------------------*/
1587 geniCodeGoto (symbol * label)
1591 ic = newiCodeLabelGoto (GOTO, label);
1595 /*-----------------------------------------------------------------*/
1596 /* geniCodeMultiply - gen intermediate code for multiplication */
1597 /*-----------------------------------------------------------------*/
1599 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1606 /* if they are both literal then we know the result */
1607 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1608 return operandFromValue (valMult (left->operand.valOperand,
1609 right->operand.valOperand));
1611 if (IS_LITERAL(retype)) {
1612 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1615 resType = usualBinaryConversions (&left, &right);
1617 rtype = operandType (right);
1618 retype = getSpec (rtype);
1619 ltype = operandType (left);
1620 letype = getSpec (ltype);
1624 SPEC_NOUN(getSpec(resType))=V_INT;
1625 SPEC_SHORT(getSpec(resType))=0;
1628 /* if the right is a literal & power of 2 */
1629 /* then make it a left shift */
1630 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1631 efficient in most cases than 2 bytes result = 2 bytes << literal
1632 if port has 1 byte muldiv */
1633 if (p2 && !IS_FLOAT (letype) &&
1634 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1635 (port->muldiv.native_below == 1)))
1637 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1639 /* LEFT_OP need same size for left and result, */
1640 left = geniCodeCast (resType, left, TRUE);
1641 ltype = operandType (left);
1643 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1647 ic = newiCode ('*', left, right); /* normal multiplication */
1648 /* if the size left or right > 1 then support routine */
1649 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1653 IC_RESULT (ic) = newiTempOperand (resType, 1);
1656 return IC_RESULT (ic);
1659 /*-----------------------------------------------------------------*/
1660 /* geniCodeDivision - gen intermediate code for division */
1661 /*-----------------------------------------------------------------*/
1663 geniCodeDivision (operand * left, operand * right)
1668 sym_link *rtype = operandType (right);
1669 sym_link *retype = getSpec (rtype);
1670 sym_link *ltype = operandType (left);
1671 sym_link *letype = getSpec (ltype);
1673 resType = usualBinaryConversions (&left, &right);
1675 /* if the right is a literal & power of 2 */
1676 /* then make it a right shift */
1677 if (IS_LITERAL (retype) &&
1678 !IS_FLOAT (letype) &&
1679 (p2 = powof2 ((unsigned long)
1680 floatFromVal (right->operand.valOperand))))
1681 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1684 ic = newiCode ('/', left, right); /* normal division */
1685 /* if the size left or right > 1 then support routine */
1686 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1689 IC_RESULT (ic) = newiTempOperand (resType, 0);
1692 return IC_RESULT (ic);
1694 /*-----------------------------------------------------------------*/
1695 /* geniCodeModulus - gen intermediate code for modulus */
1696 /*-----------------------------------------------------------------*/
1698 geniCodeModulus (operand * left, operand * right)
1704 /* if they are both literal then we know the result */
1705 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1706 return operandFromValue (valMod (left->operand.valOperand,
1707 right->operand.valOperand));
1709 resType = usualBinaryConversions (&left, &right);
1711 /* now they are the same size */
1712 ic = newiCode ('%', left, right);
1714 /* if the size left or right > 1 then support routine */
1715 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1717 IC_RESULT (ic) = newiTempOperand (resType, 0);
1720 return IC_RESULT (ic);
1723 /*-----------------------------------------------------------------*/
1724 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1725 /*-----------------------------------------------------------------*/
1727 geniCodePtrPtrSubtract (operand * left, operand * right)
1733 /* if they are both literals then */
1734 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1736 result = operandFromValue (valMinus (left->operand.valOperand,
1737 right->operand.valOperand));
1741 ic = newiCode ('-', left, right);
1743 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1747 return geniCodeDivision (result,
1748 operandFromLit (getSize (ltype->next)));
1751 /*-----------------------------------------------------------------*/
1752 /* geniCodeSubtract - generates code for subtraction */
1753 /*-----------------------------------------------------------------*/
1755 geniCodeSubtract (operand * left, operand * right)
1762 /* if they both pointers then */
1763 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1764 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1765 return geniCodePtrPtrSubtract (left, right);
1767 /* if they are both literal then we know the result */
1768 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1769 && left->isLiteral && right->isLiteral)
1770 return operandFromValue (valMinus (left->operand.valOperand,
1771 right->operand.valOperand));
1773 /* if left is an array or pointer */
1774 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1776 isarray = left->isaddr;
1777 right = geniCodeMultiply (right,
1778 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1779 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1782 { /* make them the same size */
1783 resType = usualBinaryConversions (&left, &right);
1786 ic = newiCode ('-', left, right);
1788 IC_RESULT (ic) = newiTempOperand (resType, 1);
1789 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1791 /* if left or right is a float */
1792 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1796 return IC_RESULT (ic);
1799 /*-----------------------------------------------------------------*/
1800 /* geniCodeAdd - generates iCode for addition */
1801 /*-----------------------------------------------------------------*/
1803 geniCodeAdd (operand * left, operand * right,int lvl)
1811 /* if left is an array then array access */
1812 if (IS_ARRAY (ltype))
1813 return geniCodeArray (left, right,lvl);
1815 /* if the right side is LITERAL zero */
1816 /* return the left side */
1817 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1820 /* if left is literal zero return right */
1821 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1824 /* if left is an array or pointer then size */
1827 isarray = left->isaddr;
1828 // there is no need to multiply with 1
1829 if (getSize(ltype->next)!=1) {
1830 size = operandFromLit (getSize (ltype->next));
1831 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1833 resType = copyLinkChain (ltype);
1836 { /* make them the same size */
1837 resType = usualBinaryConversions (&left, &right);
1840 /* if they are both literals then we know */
1841 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1842 && left->isLiteral && right->isLiteral)
1843 return operandFromValue (valPlus (valFromType (letype),
1844 valFromType (retype)));
1846 ic = newiCode ('+', left, right);
1848 IC_RESULT (ic) = newiTempOperand (resType, 1);
1849 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1851 /* if left or right is a float then support
1853 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1858 return IC_RESULT (ic);
1862 /*-----------------------------------------------------------------*/
1863 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1864 /*-----------------------------------------------------------------*/
1866 aggrToPtr (sym_link * type, bool force)
1872 if (IS_PTR (type) && !force)
1875 etype = getSpec (type);
1879 /* if the output class is generic */
1880 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1881 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1883 /* if the variable was declared a constant */
1884 /* then the pointer points to a constant */
1885 if (IS_CONSTANT (etype))
1886 DCL_PTR_CONST (ptype) = 1;
1888 /* the variable was volatile then pointer to volatile */
1889 if (IS_VOLATILE (etype))
1890 DCL_PTR_VOLATILE (ptype) = 1;
1894 /*-----------------------------------------------------------------*/
1895 /* geniCodeArray2Ptr - array to pointer */
1896 /*-----------------------------------------------------------------*/
1898 geniCodeArray2Ptr (operand * op)
1900 sym_link *optype = operandType (op);
1901 sym_link *opetype = getSpec (optype);
1903 /* set the pointer depending on the storage class */
1904 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1905 DCL_PTR_CONST (optype) = port->mem.code_ro;
1908 /* if the variable was declared a constant */
1909 /* then the pointer points to a constant */
1910 if (IS_CONSTANT (opetype))
1911 DCL_PTR_CONST (optype) = 1;
1913 /* the variable was volatile then pointer to volatile */
1914 if (IS_VOLATILE (opetype))
1915 DCL_PTR_VOLATILE (optype) = 1;
1921 /*-----------------------------------------------------------------*/
1922 /* geniCodeArray - array access */
1923 /*-----------------------------------------------------------------*/
1925 geniCodeArray (operand * left, operand * right,int lvl)
1928 sym_link *ltype = operandType (left);
1932 if (IS_PTR (ltype->next) && left->isaddr)
1934 left = geniCodeRValue (left, FALSE);
1936 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
1939 right = geniCodeMultiply (right,
1940 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1942 /* we can check for limits here */
1943 if (isOperandLiteral (right) &&
1946 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
1948 werror (E_ARRAY_BOUND);
1949 right = operandFromLit (0);
1952 ic = newiCode ('+', left, right);
1954 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
1955 !IS_AGGREGATE (ltype->next) &&
1956 !IS_PTR (ltype->next))
1957 ? ltype : ltype->next), 0);
1959 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
1961 return IC_RESULT (ic);
1964 /*-----------------------------------------------------------------*/
1965 /* geniCodeStruct - generates intermediate code for structres */
1966 /*-----------------------------------------------------------------*/
1968 geniCodeStruct (operand * left, operand * right, bool islval)
1971 sym_link *type = operandType (left);
1972 sym_link *etype = getSpec (type);
1974 symbol *element = getStructElement (SPEC_STRUCT (etype),
1975 right->operand.symOperand);
1977 /* add the offset */
1978 ic = newiCode ('+', left, operandFromLit (element->offset));
1980 IC_RESULT (ic) = newiTempOperand (element->type, 0);
1982 /* preserve the storage & output class of the struct */
1983 /* as well as the volatile attribute */
1984 retype = getSpec (operandType (IC_RESULT (ic)));
1985 SPEC_SCLS (retype) = SPEC_SCLS (etype);
1986 SPEC_OCLS (retype) = SPEC_OCLS (etype);
1987 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
1989 if (IS_PTR (element->type))
1990 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1992 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
1996 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
1999 /*-----------------------------------------------------------------*/
2000 /* geniCodePostInc - generate int code for Post increment */
2001 /*-----------------------------------------------------------------*/
2003 geniCodePostInc (operand * op)
2007 sym_link *optype = operandType (op);
2009 operand *rv = (IS_ITEMP (op) ?
2010 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2012 sym_link *rvtype = operandType (rv);
2015 /* if this is not an address we have trouble */
2018 werror (E_LVALUE_REQUIRED, "++");
2022 rOp = newiTempOperand (rvtype, 0);
2028 geniCodeAssign (rOp, rv, 0);
2030 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2031 if (IS_FLOAT (rvtype))
2032 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2034 ic = newiCode ('+', rv, operandFromLit (size));
2036 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2039 geniCodeAssign (op, result, 0);
2045 /*-----------------------------------------------------------------*/
2046 /* geniCodePreInc - generate code for preIncrement */
2047 /*-----------------------------------------------------------------*/
2049 geniCodePreInc (operand * op)
2052 sym_link *optype = operandType (op);
2053 operand *rop = (IS_ITEMP (op) ?
2054 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2056 sym_link *roptype = operandType (rop);
2062 werror (E_LVALUE_REQUIRED, "++");
2067 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2068 if (IS_FLOAT (roptype))
2069 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2071 ic = newiCode ('+', rop, operandFromLit (size));
2072 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2076 return geniCodeAssign (op, result, 0);
2079 /*-----------------------------------------------------------------*/
2080 /* geniCodePostDec - generates code for Post decrement */
2081 /*-----------------------------------------------------------------*/
2083 geniCodePostDec (operand * op)
2087 sym_link *optype = operandType (op);
2089 operand *rv = (IS_ITEMP (op) ?
2090 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2092 sym_link *rvtype = operandType (rv);
2095 /* if this is not an address we have trouble */
2098 werror (E_LVALUE_REQUIRED, "++");
2102 rOp = newiTempOperand (rvtype, 0);
2108 geniCodeAssign (rOp, rv, 0);
2110 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2111 if (IS_FLOAT (rvtype))
2112 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2114 ic = newiCode ('-', rv, operandFromLit (size));
2116 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2119 geniCodeAssign (op, result, 0);
2125 /*-----------------------------------------------------------------*/
2126 /* geniCodePreDec - generate code for pre decrement */
2127 /*-----------------------------------------------------------------*/
2129 geniCodePreDec (operand * op)
2132 sym_link *optype = operandType (op);
2133 operand *rop = (IS_ITEMP (op) ?
2134 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2136 sym_link *roptype = operandType (rop);
2142 werror (E_LVALUE_REQUIRED, "++");
2147 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2148 if (IS_FLOAT (roptype))
2149 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2151 ic = newiCode ('-', rop, operandFromLit (size));
2152 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2156 return geniCodeAssign (op, result, 0);
2160 /*-----------------------------------------------------------------*/
2161 /* geniCodeBitwise - gen int code for bitWise operators */
2162 /*-----------------------------------------------------------------*/
2164 geniCodeBitwise (operand * left, operand * right,
2165 int oper, sym_link * resType)
2169 left = geniCodeCast (resType, left, TRUE);
2170 right = geniCodeCast (resType, right, TRUE);
2172 ic = newiCode (oper, left, right);
2173 IC_RESULT (ic) = newiTempOperand (resType, 0);
2176 return IC_RESULT (ic);
2179 /*-----------------------------------------------------------------*/
2180 /* geniCodeAddressOf - gens icode for '&' address of operator */
2181 /*-----------------------------------------------------------------*/
2183 geniCodeAddressOf (operand * op)
2187 sym_link *optype = operandType (op);
2188 sym_link *opetype = getSpec (optype);
2190 /* lvalue check already done in decorateType */
2191 /* this must be a lvalue */
2192 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2193 /* werror (E_LVALUE_REQUIRED,"&"); */
2198 p->class = DECLARATOR;
2200 /* set the pointer depending on the storage class */
2201 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2202 DCL_PTR_CONST (p) = port->mem.code_ro;
2204 /* make sure we preserve the const & volatile */
2205 if (IS_CONSTANT (opetype))
2206 DCL_PTR_CONST (p) = 1;
2208 if (IS_VOLATILE (opetype))
2209 DCL_PTR_VOLATILE (p) = 1;
2211 p->next = copyLinkChain (optype);
2213 /* if already a temp */
2216 setOperandType (op, p);
2221 /* other wise make this of the type coming in */
2222 ic = newiCode (ADDRESS_OF, op, NULL);
2223 IC_RESULT (ic) = newiTempOperand (p, 1);
2224 IC_RESULT (ic)->isaddr = 0;
2226 return IC_RESULT (ic);
2228 /*-----------------------------------------------------------------*/
2229 /* setOClass - sets the output class depending on the pointer type */
2230 /*-----------------------------------------------------------------*/
2232 setOClass (sym_link * ptr, sym_link * spec)
2234 switch (DCL_TYPE (ptr))
2237 SPEC_OCLS (spec) = data;
2241 SPEC_OCLS (spec) = generic;
2245 SPEC_OCLS (spec) = xdata;
2249 SPEC_OCLS (spec) = code;
2253 SPEC_OCLS (spec) = idata;
2257 SPEC_OCLS (spec) = xstack;
2261 SPEC_OCLS (spec) = eeprom;
2270 /*-----------------------------------------------------------------*/
2271 /* geniCodeDerefPtr - dereference pointer with '*' */
2272 /*-----------------------------------------------------------------*/
2274 geniCodeDerefPtr (operand * op,int lvl)
2276 sym_link *rtype, *retype;
2277 sym_link *optype = operandType (op);
2279 /* if this is a pointer then generate the rvalue */
2280 if (IS_PTR (optype))
2282 if (IS_TRUE_SYMOP (op))
2285 op = geniCodeRValue (op, TRUE);
2288 op = geniCodeRValue (op, TRUE);
2291 /* now get rid of the pointer part */
2292 if (isLvaluereq(lvl) && IS_ITEMP (op))
2294 retype = getSpec (rtype = copyLinkChain (optype));
2298 retype = getSpec (rtype = copyLinkChain (optype->next));
2301 /* if this is a pointer then outputclass needs 2b updated */
2302 if (IS_PTR (optype))
2303 setOClass (optype, retype);
2305 op->isGptr = IS_GENPTR (optype);
2307 /* if the pointer was declared as a constant */
2308 /* then we cannot allow assignment to the derefed */
2309 if (IS_PTR_CONST (optype))
2310 SPEC_CONST (retype) = 1;
2312 op->isaddr = (IS_PTR (rtype) ||
2313 IS_STRUCT (rtype) ||
2318 if (!isLvaluereq(lvl))
2319 op = geniCodeRValue (op, TRUE);
2321 setOperandType (op, rtype);
2326 /*-----------------------------------------------------------------*/
2327 /* geniCodeUnaryMinus - does a unary minus of the operand */
2328 /*-----------------------------------------------------------------*/
2330 geniCodeUnaryMinus (operand * op)
2333 sym_link *optype = operandType (op);
2335 if (IS_LITERAL (optype))
2336 return operandFromLit (-floatFromVal (op->operand.valOperand));
2338 ic = newiCode (UNARYMINUS, op, NULL);
2339 IC_RESULT (ic) = newiTempOperand (optype, 0);
2341 return IC_RESULT (ic);
2344 /*-----------------------------------------------------------------*/
2345 /* geniCodeLeftShift - gen i code for left shift */
2346 /*-----------------------------------------------------------------*/
2348 geniCodeLeftShift (operand * left, operand * right)
2352 ic = newiCode (LEFT_OP, left, right);
2353 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2355 return IC_RESULT (ic);
2358 /*-----------------------------------------------------------------*/
2359 /* geniCodeRightShift - gen i code for right shift */
2360 /*-----------------------------------------------------------------*/
2362 geniCodeRightShift (operand * left, operand * right)
2366 ic = newiCode (RIGHT_OP, left, right);
2367 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2369 return IC_RESULT (ic);
2372 #if defined(__BORLANDC__) || defined(_MSC_VER)
2373 #define LONG_LONG __int64
2375 #define LONG_LONG long long
2378 /*-----------------------------------------------------------------*/
2379 /* geniCodeLogic- logic code */
2380 /*-----------------------------------------------------------------*/
2382 geniCodeLogic (operand * left, operand * right, int op)
2386 sym_link *rtype = operandType (right);
2387 sym_link *ltype = operandType (left);
2389 /* left is integral type and right is literal then
2390 check if the literal value is within bounds */
2391 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2393 int nbits = bitsForType (ltype);
2394 long v = operandLitValue (right);
2396 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2397 werror (W_CONST_RANGE, " compare operation ");
2400 ctype = usualBinaryConversions (&left, &right);
2402 ic = newiCode (op, left, right);
2403 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2405 /* if comparing float
2406 and not a '==' || '!=' || '&&' || '||' (these
2408 if (IS_FLOAT(ctype) &&
2416 return IC_RESULT (ic);
2419 /*-----------------------------------------------------------------*/
2420 /* geniCodeUnary - for a a generic unary operation */
2421 /*-----------------------------------------------------------------*/
2423 geniCodeUnary (operand * op, int oper)
2425 iCode *ic = newiCode (oper, op, NULL);
2427 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2429 return IC_RESULT (ic);
2432 /*-----------------------------------------------------------------*/
2433 /* geniCodeConditional - geniCode for '?' ':' operation */
2434 /*-----------------------------------------------------------------*/
2436 geniCodeConditional (ast * tree,int lvl)
2439 symbol *falseLabel = newiTempLabel (NULL);
2440 symbol *exitLabel = newiTempLabel (NULL);
2441 operand *cond = ast2iCode (tree->left,lvl+1);
2442 operand *true, *false, *result;
2444 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2448 true = ast2iCode (tree->right->left,lvl+1);
2450 /* move the value to a new Operand */
2451 result = newiTempOperand (operandType (true), 0);
2452 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2454 /* generate an unconditional goto */
2455 geniCodeGoto (exitLabel);
2457 /* now for the right side */
2458 geniCodeLabel (falseLabel);
2460 false = ast2iCode (tree->right->right,lvl+1);
2461 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2463 /* create the exit label */
2464 geniCodeLabel (exitLabel);
2469 /*-----------------------------------------------------------------*/
2470 /* geniCodeAssign - generate code for assignment */
2471 /*-----------------------------------------------------------------*/
2473 geniCodeAssign (operand * left, operand * right, int nosupdate)
2476 sym_link *ltype = operandType (left);
2477 sym_link *rtype = operandType (right);
2479 if (!left->isaddr && !IS_ITEMP (left))
2481 werror (E_LVALUE_REQUIRED, "assignment");
2485 /* left is integral type and right is literal then
2486 check if the literal value is within bounds */
2487 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2489 int nbits = bitsForType (ltype);
2490 long v = operandLitValue (right);
2492 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2493 werror (W_CONST_RANGE, " = operation");
2496 /* if the left & right type don't exactly match */
2497 /* if pointer set then make sure the check is
2498 done with the type & not the pointer */
2499 /* then cast rights type to left */
2501 /* first check the type for pointer assignement */
2502 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2503 checkType (ltype, rtype) < 0)
2505 if (checkType (ltype->next, rtype) < 0)
2506 right = geniCodeCast (ltype->next, right, TRUE);
2508 else if (checkType (ltype, rtype) < 0)
2509 right = geniCodeCast (ltype, right, TRUE);
2511 /* if left is a true symbol & ! volatile
2512 create an assignment to temporary for
2513 the right & then assign this temporary
2514 to the symbol this is SSA . isn't it simple
2515 and folks have published mountains of paper on it */
2516 if (IS_TRUE_SYMOP (left) &&
2517 !isOperandVolatile (left, FALSE) &&
2518 isOperandGlobal (left))
2522 if (IS_TRUE_SYMOP (right))
2523 sym = OP_SYMBOL (right);
2524 ic = newiCode ('=', NULL, right);
2525 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2526 SPIL_LOC (right) = sym;
2530 ic = newiCode ('=', NULL, right);
2531 IC_RESULT (ic) = left;
2534 /* if left isgptr flag is set then support
2535 routine will be required */
2539 ic->nosupdate = nosupdate;
2543 /*-----------------------------------------------------------------*/
2544 /* geniCodeSEParms - generate code for side effecting fcalls */
2545 /*-----------------------------------------------------------------*/
2547 geniCodeSEParms (ast * parms,int lvl)
2552 if (parms->type == EX_OP && parms->opval.op == PARAM)
2554 geniCodeSEParms (parms->left,lvl);
2555 geniCodeSEParms (parms->right,lvl);
2559 /* hack don't like this but too lazy to think of
2561 if (IS_ADDRESS_OF_OP (parms))
2562 parms->left->lvalue = 1;
2564 if (IS_CAST_OP (parms) &&
2565 IS_PTR (parms->ftype) &&
2566 IS_ADDRESS_OF_OP (parms->right))
2567 parms->right->left->lvalue = 1;
2569 parms->opval.oprnd =
2570 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2572 parms->type = EX_OPERAND;
2575 /*-----------------------------------------------------------------*/
2576 /* geniCodeParms - generates parameters */
2577 /*-----------------------------------------------------------------*/
2579 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2587 /* if this is a param node then do the left & right */
2588 if (parms->type == EX_OP && parms->opval.op == PARAM)
2590 geniCodeParms (parms->left, stack, fetype, func,lvl);
2591 geniCodeParms (parms->right, stack, fetype, func,lvl);
2595 /* get the parameter value */
2596 if (parms->type == EX_OPERAND)
2597 pval = parms->opval.oprnd;
2600 /* maybe this else should go away ?? */
2601 /* hack don't like this but too lazy to think of
2603 if (IS_ADDRESS_OF_OP (parms))
2604 parms->left->lvalue = 1;
2606 if (IS_CAST_OP (parms) &&
2607 IS_PTR (parms->ftype) &&
2608 IS_ADDRESS_OF_OP (parms->right))
2609 parms->right->left->lvalue = 1;
2611 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2614 /* if register parm then make it a send */
2615 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2616 IS_REGPARM (parms->etype)) && !func->hasVargs)
2618 ic = newiCode (SEND, pval, NULL);
2623 /* now decide whether to push or assign */
2624 if (!(options.stackAuto || IS_RENT (fetype)))
2628 operand *top = operandFromSymbol (parms->argSym);
2629 geniCodeAssign (top, pval, 1);
2633 sym_link *p = operandType (pval);
2635 ic = newiCode (IPUSH, pval, NULL);
2637 /* update the stack adjustment */
2638 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2645 /*-----------------------------------------------------------------*/
2646 /* geniCodeCall - generates temp code for calling */
2647 /*-----------------------------------------------------------------*/
2649 geniCodeCall (operand * left, ast * parms,int lvl)
2653 sym_link *type, *etype;
2656 /* take care of parameters with side-effecting
2657 function calls in them, this is required to take care
2658 of overlaying function parameters */
2659 geniCodeSEParms (parms,lvl);
2661 /* first the parameters */
2662 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2664 /* now call : if symbol then pcall */
2665 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2666 ic = newiCode (PCALL, left, NULL);
2668 ic = newiCode (CALL, left, NULL);
2670 IC_ARGS (ic) = left->operand.symOperand->args;
2671 type = copyLinkChain (operandType (left)->next);
2672 etype = getSpec (type);
2673 SPEC_EXTR (etype) = 0;
2674 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2678 /* stack adjustment after call */
2679 ic->parmBytes = stack;
2684 /*-----------------------------------------------------------------*/
2685 /* geniCodeReceive - generate intermediate code for "receive" */
2686 /*-----------------------------------------------------------------*/
2688 geniCodeReceive (value * args)
2690 /* for all arguments that are passed in registers */
2694 if (IS_REGPARM (args->etype))
2696 operand *opr = operandFromValue (args);
2698 symbol *sym = OP_SYMBOL (opr);
2701 /* we will use it after all optimizations
2702 and before liveRange calculation */
2703 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2706 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2707 options.stackAuto == 0 &&
2713 opl = newiTempOperand (args->type, 0);
2715 sym->reqv->key = sym->key;
2716 OP_SYMBOL (sym->reqv)->key = sym->key;
2717 OP_SYMBOL (sym->reqv)->isreqv = 1;
2718 OP_SYMBOL (sym->reqv)->islocal = 0;
2719 SPIL_LOC (sym->reqv) = sym;
2723 ic = newiCode (RECEIVE, NULL, NULL);
2724 currFunc->recvSize = getSize (sym->etype);
2725 IC_RESULT (ic) = opr;
2733 /*-----------------------------------------------------------------*/
2734 /* geniCodeFunctionBody - create the function body */
2735 /*-----------------------------------------------------------------*/
2737 geniCodeFunctionBody (ast * tree,int lvl)
2744 /* reset the auto generation */
2750 func = ast2iCode (tree->left,lvl+1);
2751 fetype = getSpec (operandType (func));
2753 savelineno = lineno;
2754 lineno = OP_SYMBOL (func)->lineDef;
2755 /* create an entry label */
2756 geniCodeLabel (entryLabel);
2757 lineno = savelineno;
2759 /* create a proc icode */
2760 ic = newiCode (FUNCTION, func, NULL);
2761 /* if the function has parmas then */
2762 /* save the parameters information */
2763 ic->argLabel.args = tree->values.args;
2764 ic->lineno = OP_SYMBOL (func)->lineDef;
2768 /* for all parameters that are passed
2769 on registers add a "receive" */
2770 geniCodeReceive (tree->values.args);
2772 /* generate code for the body */
2773 ast2iCode (tree->right,lvl+1);
2775 /* create a label for return */
2776 geniCodeLabel (returnLabel);
2778 /* now generate the end proc */
2779 ic = newiCode (ENDFUNCTION, func, NULL);
2784 /*-----------------------------------------------------------------*/
2785 /* geniCodeReturn - gen icode for 'return' statement */
2786 /*-----------------------------------------------------------------*/
2788 geniCodeReturn (operand * op)
2792 /* if the operand is present force an rvalue */
2794 op = geniCodeRValue (op, FALSE);
2796 ic = newiCode (RETURN, op, NULL);
2800 /*-----------------------------------------------------------------*/
2801 /* geniCodeIfx - generates code for extended if statement */
2802 /*-----------------------------------------------------------------*/
2804 geniCodeIfx (ast * tree,int lvl)
2807 operand *condition = ast2iCode (tree->left,lvl+1);
2810 /* if condition is null then exit */
2814 condition = geniCodeRValue (condition, FALSE);
2816 cetype = getSpec (operandType (condition));
2817 /* if the condition is a literal */
2818 if (IS_LITERAL (cetype))
2820 if (floatFromVal (condition->operand.valOperand))
2822 if (tree->trueLabel)
2823 geniCodeGoto (tree->trueLabel);
2829 if (tree->falseLabel)
2830 geniCodeGoto (tree->falseLabel);
2837 if (tree->trueLabel)
2839 ic = newiCodeCondition (condition,
2844 if (tree->falseLabel)
2845 geniCodeGoto (tree->falseLabel);
2849 ic = newiCodeCondition (condition,
2856 ast2iCode (tree->right,lvl+1);
2859 /*-----------------------------------------------------------------*/
2860 /* geniCodeJumpTable - tries to create a jump table for switch */
2861 /*-----------------------------------------------------------------*/
2863 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2865 int min = 0, max = 0, t, cnt = 0;
2872 if (!tree || !caseVals)
2875 /* the criteria for creating a jump table is */
2876 /* all integer numbers between the maximum & minimum must */
2877 /* be present , the maximum value should not exceed 255 */
2878 min = max = (int) floatFromVal (vch = caseVals);
2879 sprintf (buffer, "_case_%d_%d",
2880 tree->values.switchVals.swNum,
2882 addSet (&labels, newiTempLabel (buffer));
2884 /* if there is only one case value then no need */
2885 if (!(vch = vch->next))
2890 if (((t = (int) floatFromVal (vch)) - max) != 1)
2892 sprintf (buffer, "_case_%d_%d",
2893 tree->values.switchVals.swNum,
2895 addSet (&labels, newiTempLabel (buffer));
2901 /* if the number of case statements <= 2 then */
2902 /* it is not economical to create the jump table */
2903 /* since two compares are needed for boundary conditions */
2904 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2907 if (tree->values.switchVals.swDefault)
2908 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2910 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2912 falseLabel = newiTempLabel (buffer);
2914 /* so we can create a jumptable */
2915 /* first we rule out the boundary conditions */
2916 /* if only optimization says so */
2917 if (!optimize.noJTabBoundary)
2919 sym_link *cetype = getSpec (operandType (cond));
2920 /* no need to check the lower bound if
2921 the condition is unsigned & minimum value is zero */
2922 if (!(min == 0 && SPEC_USIGN (cetype)))
2924 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2925 ic = newiCodeCondition (boundary, falseLabel, NULL);
2929 /* now for upper bounds */
2930 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
2931 ic = newiCodeCondition (boundary, falseLabel, NULL);
2935 /* if the min is not zero then we no make it zero */
2938 cond = geniCodeSubtract (cond, operandFromLit (min));
2939 setOperandType (cond, UCHARTYPE);
2942 /* now create the jumptable */
2943 ic = newiCode (JUMPTABLE, NULL, NULL);
2944 IC_JTCOND (ic) = cond;
2945 IC_JTLABELS (ic) = labels;
2950 /*-----------------------------------------------------------------*/
2951 /* geniCodeSwitch - changes a switch to a if statement */
2952 /*-----------------------------------------------------------------*/
2954 geniCodeSwitch (ast * tree,int lvl)
2957 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
2958 value *caseVals = tree->values.switchVals.swVals;
2959 symbol *trueLabel, *falseLabel;
2961 /* if we can make this a jump table */
2962 if (geniCodeJumpTable (cond, caseVals, tree))
2963 goto jumpTable; /* no need for the comparison */
2965 /* for the cases defined do */
2969 operand *compare = geniCodeLogic (cond,
2970 operandFromValue (caseVals),
2973 sprintf (buffer, "_case_%d_%d",
2974 tree->values.switchVals.swNum,
2975 (int) floatFromVal (caseVals));
2976 trueLabel = newiTempLabel (buffer);
2978 ic = newiCodeCondition (compare, trueLabel, NULL);
2980 caseVals = caseVals->next;
2985 /* if default is present then goto break else break */
2986 if (tree->values.switchVals.swDefault)
2987 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2989 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2991 falseLabel = newiTempLabel (buffer);
2992 geniCodeGoto (falseLabel);
2995 ast2iCode (tree->right,lvl+1);
2998 /*-----------------------------------------------------------------*/
2999 /* geniCodeInline - intermediate code for inline assembler */
3000 /*-----------------------------------------------------------------*/
3002 geniCodeInline (ast * tree)
3006 ic = newiCode (INLINEASM, NULL, NULL);
3007 IC_INLINE (ic) = tree->values.inlineasm;
3011 /*-----------------------------------------------------------------*/
3012 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3013 /* particular case. Ie : assigning or dereferencing array or ptr */
3014 /*-----------------------------------------------------------------*/
3015 set * lvaluereqSet = NULL;
3016 typedef struct lvalItem
3023 /*-----------------------------------------------------------------*/
3024 /* addLvaluereq - add a flag for lvalreq for current ast level */
3025 /*-----------------------------------------------------------------*/
3026 void addLvaluereq(int lvl)
3028 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3031 addSetHead(&lvaluereqSet,lpItem);
3034 /*-----------------------------------------------------------------*/
3035 /* delLvaluereq - del a flag for lvalreq for current ast level */
3036 /*-----------------------------------------------------------------*/
3040 lpItem = getSet(&lvaluereqSet);
3041 if(lpItem) free(lpItem);
3043 /*-----------------------------------------------------------------*/
3044 /* clearLvaluereq - clear lvalreq flag */
3045 /*-----------------------------------------------------------------*/
3046 void clearLvaluereq()
3049 lpItem = peekSet(lvaluereqSet);
3050 if(lpItem) lpItem->req = 0;
3052 /*-----------------------------------------------------------------*/
3053 /* getLvaluereq - get the last lvalreq level */
3054 /*-----------------------------------------------------------------*/
3055 int getLvaluereqLvl()
3058 lpItem = peekSet(lvaluereqSet);
3059 if(lpItem) return lpItem->lvl;
3062 /*-----------------------------------------------------------------*/
3063 /* isLvaluereq - is lvalreq valid for this level ? */
3064 /*-----------------------------------------------------------------*/
3065 int isLvaluereq(int lvl)
3068 lpItem = peekSet(lvaluereqSet);
3069 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3073 /*-----------------------------------------------------------------*/
3074 /* ast2iCode - creates an icodeList from an ast */
3075 /*-----------------------------------------------------------------*/
3077 ast2iCode (ast * tree,int lvl)
3079 operand *left = NULL;
3080 operand *right = NULL;
3083 /* set the global variables for filename & line number */
3085 filename = tree->filename;
3087 lineno = tree->lineno;
3089 block = tree->block;
3091 scopeLevel = tree->level;
3093 if (tree->type == EX_VALUE)
3094 return operandFromValue (tree->opval.val);
3096 if (tree->type == EX_LINK)
3097 return operandFromLink (tree->opval.lnk);
3099 /* if we find a nullop */
3100 if (tree->type == EX_OP &&
3101 (tree->opval.op == NULLOP ||
3102 tree->opval.op == BLOCK))
3104 ast2iCode (tree->left,lvl+1);
3105 ast2iCode (tree->right,lvl+1);
3109 /* special cases for not evaluating */
3110 if (tree->opval.op != ':' &&
3111 tree->opval.op != '?' &&
3112 tree->opval.op != CALL &&
3113 tree->opval.op != IFX &&
3114 tree->opval.op != LABEL &&
3115 tree->opval.op != GOTO &&
3116 tree->opval.op != SWITCH &&
3117 tree->opval.op != FUNCTION &&
3118 tree->opval.op != INLINEASM)
3121 if (IS_ASSIGN_OP (tree->opval.op) ||
3122 IS_DEREF_OP (tree) ||
3123 (tree->opval.op == '&' && !tree->right) ||
3124 tree->opval.op == PTR_OP)
3127 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3128 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3131 left = operandFromAst (tree->left,lvl);
3133 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3134 left = geniCodeRValue (left, TRUE);
3138 left = operandFromAst (tree->left,lvl);
3140 if (tree->opval.op == INC_OP ||
3141 tree->opval.op == DEC_OP)
3144 right = operandFromAst (tree->right,lvl);
3149 right = operandFromAst (tree->right,lvl);
3153 /* now depending on the type of operand */
3154 /* this will be a biggy */
3155 switch (tree->opval.op)
3158 case '[': /* array operation */
3160 sym_link *ltype = operandType (left);
3161 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3162 right = geniCodeRValue (right, TRUE);
3165 return geniCodeArray (left, right,lvl);
3167 case '.': /* structure dereference */
3168 if (IS_PTR (operandType (left)))
3169 left = geniCodeRValue (left, TRUE);
3171 left = geniCodeRValue (left, FALSE);
3173 return geniCodeStruct (left, right, tree->lvalue);
3175 case PTR_OP: /* structure pointer dereference */
3178 pType = operandType (left);
3179 left = geniCodeRValue (left, TRUE);
3181 setOClass (pType, getSpec (operandType (left)));
3184 return geniCodeStruct (left, right, tree->lvalue);
3186 case INC_OP: /* increment operator */
3188 return geniCodePostInc (left);
3190 return geniCodePreInc (right);
3192 case DEC_OP: /* decrement operator */
3194 return geniCodePostDec (left);
3196 return geniCodePreDec (right);
3198 case '&': /* bitwise and or address of operator */
3200 { /* this is a bitwise operator */
3201 left = geniCodeRValue (left, FALSE);
3202 right = geniCodeRValue (right, FALSE);
3203 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3206 return geniCodeAddressOf (left);
3208 case '|': /* bitwise or & xor */
3210 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3211 geniCodeRValue (right, FALSE),
3216 return geniCodeDivision (geniCodeRValue (left, FALSE),
3217 geniCodeRValue (right, FALSE));
3220 return geniCodeModulus (geniCodeRValue (left, FALSE),
3221 geniCodeRValue (right, FALSE));
3224 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3225 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3227 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3231 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3232 geniCodeRValue (right, FALSE));
3234 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3238 return geniCodeAdd (geniCodeRValue (left, FALSE),
3239 geniCodeRValue (right, FALSE),lvl);
3241 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3244 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3245 geniCodeRValue (right, FALSE));
3248 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3249 geniCodeRValue (right, FALSE));
3251 return geniCodeCast (operandType (left),
3252 geniCodeRValue (right, FALSE), FALSE);
3258 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3262 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3263 setOperandType (op, UCHARTYPE);
3274 return geniCodeLogic (geniCodeRValue (left, FALSE),
3275 geniCodeRValue (right, FALSE),
3278 return geniCodeConditional (tree,lvl);
3281 return operandFromLit (getSize (tree->right->ftype));
3285 sym_link *rtype = operandType (right);
3286 sym_link *ltype = operandType (left);
3287 if (IS_PTR (rtype) && IS_ITEMP (right)
3288 && right->isaddr && checkType (rtype->next, ltype) == 1)
3289 right = geniCodeRValue (right, TRUE);
3291 right = geniCodeRValue (right, FALSE);
3293 geniCodeAssign (left, right, 0);
3298 geniCodeAssign (left,
3299 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3301 geniCodeRValue (right, FALSE),FALSE), 0);
3305 geniCodeAssign (left,
3306 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3308 geniCodeRValue (right, FALSE)), 0);
3311 geniCodeAssign (left,
3312 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3314 geniCodeRValue (right, FALSE)), 0);
3317 sym_link *rtype = operandType (right);
3318 sym_link *ltype = operandType (left);
3319 if (IS_PTR (rtype) && IS_ITEMP (right)
3320 && right->isaddr && checkType (rtype->next, ltype) == 1)
3321 right = geniCodeRValue (right, TRUE);
3323 right = geniCodeRValue (right, FALSE);
3326 return geniCodeAssign (left,
3327 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3333 sym_link *rtype = operandType (right);
3334 sym_link *ltype = operandType (left);
3335 if (IS_PTR (rtype) && IS_ITEMP (right)
3336 && right->isaddr && checkType (rtype->next, ltype) == 1)
3338 right = geniCodeRValue (right, TRUE);
3342 right = geniCodeRValue (right, FALSE);
3345 geniCodeAssign (left,
3346 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3352 geniCodeAssign (left,
3353 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3355 geniCodeRValue (right, FALSE)), 0);
3358 geniCodeAssign (left,
3359 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3361 geniCodeRValue (right, FALSE)), 0);
3364 geniCodeAssign (left,
3365 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3367 geniCodeRValue (right, FALSE),
3369 operandType (left)), 0);
3372 geniCodeAssign (left,
3373 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3375 geniCodeRValue (right, FALSE),
3377 operandType (left)), 0);
3380 geniCodeAssign (left,
3381 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3383 geniCodeRValue (right, FALSE),
3385 operandType (left)), 0);
3387 return geniCodeRValue (right, FALSE);
3390 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3393 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3394 return ast2iCode (tree->right,lvl+1);
3397 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3398 return ast2iCode (tree->right,lvl+1);
3401 geniCodeFunctionBody (tree,lvl);
3405 geniCodeReturn (right);
3409 geniCodeIfx (tree,lvl);
3413 geniCodeSwitch (tree,lvl);
3417 geniCodeInline (tree);
3424 /*-----------------------------------------------------------------*/
3425 /* reverseICChain - gets from the list and creates a linkedlist */
3426 /*-----------------------------------------------------------------*/
3433 while ((loop = getSet (&iCodeChain)))
3445 /*-----------------------------------------------------------------*/
3446 /* iCodeFromAst - given an ast will convert it to iCode */
3447 /*-----------------------------------------------------------------*/
3449 iCodeFromAst (ast * tree)
3451 returnLabel = newiTempLabel ("_return");
3452 entryLabel = newiTempLabel ("_entry");
3454 return reverseiCChain ();