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 operand *retval = (operand *) 0;
843 assert (isOperandLiteral (left));
845 assert (isOperandLiteral (right));
850 retval = operandFromValue (valCastLiteral (type,
851 operandLitValue (left) +
852 operandLitValue (right)));
855 retval = operandFromValue (valCastLiteral (type,
856 operandLitValue (left) -
857 operandLitValue (right)));
860 retval = operandFromValue (valCastLiteral (type,
861 operandLitValue (left) *
862 operandLitValue (right)));
865 if ((unsigned long) operandLitValue (right) == 0)
867 werror (E_DIVIDE_BY_ZERO);
872 retval = operandFromValue (valCastLiteral (type,
873 operandLitValue (left) /
874 operandLitValue (right)));
877 if ((unsigned long) operandLitValue (right) == 0)
879 werror (E_DIVIDE_BY_ZERO);
883 retval = operandFromLit ((unsigned long) operandLitValue (left) %
884 (unsigned long) operandLitValue (right));
887 retval = operandFromLit ((unsigned long) operandLitValue (left) <<
888 (unsigned long) operandLitValue (right));
891 retval = operandFromLit ((unsigned long) operandLitValue (left) >>
892 (unsigned long) operandLitValue (right));
895 retval = operandFromLit (operandLitValue (left) ==
896 operandLitValue (right));
899 retval = operandFromLit (operandLitValue (left) <
900 operandLitValue (right));
903 retval = operandFromLit (operandLitValue (left) <=
904 operandLitValue (right));
907 retval = operandFromLit (operandLitValue (left) !=
908 operandLitValue (right));
911 retval = operandFromLit (operandLitValue (left) >
912 operandLitValue (right));
915 retval = operandFromLit (operandLitValue (left) >=
916 operandLitValue (right));
919 retval = operandFromLit ((unsigned long) operandLitValue (left) &
920 (unsigned long) operandLitValue (right));
923 retval = operandFromLit ((unsigned long) operandLitValue (left) |
924 (unsigned long) operandLitValue (right));
927 retval = operandFromLit ((unsigned long) operandLitValue (left) ^
928 (unsigned long) operandLitValue (right));
931 retval = operandFromLit (operandLitValue (left) &&
932 operandLitValue (right));
935 retval = operandFromLit (operandLitValue (left) ||
936 operandLitValue (right));
940 long i = operandLitValue (left);
942 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
948 long i = operandLitValue (left);
950 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
956 retval = operandFromLit (-1 * operandLitValue (left));
960 retval = operandFromLit (~((long) operandLitValue (left)));
964 retval = operandFromLit (!operandLitValue (left));
968 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
969 " operandOperation invalid operator ");
977 /*-----------------------------------------------------------------*/
978 /* isOperandEqual - compares two operand & return 1 if they r = */
979 /*-----------------------------------------------------------------*/
981 isOperandEqual (operand * left, operand * right)
983 /* if the pointers are equal then they are equal */
987 /* if either of them null then false */
991 if (left->type != right->type)
994 if (IS_SYMOP (left) && IS_SYMOP (right))
995 return left->key == right->key;
997 /* if types are the same */
1001 return isSymbolEqual (left->operand.symOperand,
1002 right->operand.symOperand);
1004 return (floatFromVal (left->operand.valOperand) ==
1005 floatFromVal (right->operand.valOperand));
1007 if (checkType (left->operand.typeOperand,
1008 right->operand.typeOperand) == 1)
1015 /*-----------------------------------------------------------------*/
1016 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1017 /*-----------------------------------------------------------------*/
1019 isiCodeEqual (iCode * left, iCode * right)
1021 /* if the same pointer */
1025 /* if either of them null */
1026 if (!left || !right)
1029 /* if operand are the same */
1030 if (left->op == right->op)
1033 /* compare all the elements depending on type */
1034 if (left->op != IFX)
1036 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1038 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1044 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1046 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1048 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1056 /*-----------------------------------------------------------------*/
1057 /* newiTempFromOp - create a temp Operand with same attributes */
1058 /*-----------------------------------------------------------------*/
1060 newiTempFromOp (operand * op)
1070 nop = newiTempOperand (operandType (op), TRUE);
1071 nop->isaddr = op->isaddr;
1072 nop->isvolatile = op->isvolatile;
1073 nop->isGlobal = op->isGlobal;
1074 nop->isLiteral = op->isLiteral;
1075 nop->noSpilLoc = op->noSpilLoc;
1076 nop->usesDefs = op->usesDefs;
1077 nop->isParm = op->isParm;
1081 /*-----------------------------------------------------------------*/
1082 /* operand from operand - creates an operand holder for the type */
1083 /*-----------------------------------------------------------------*/
1085 operandFromOperand (operand * op)
1091 nop = newOperand ();
1092 nop->type = op->type;
1093 nop->isaddr = op->isaddr;
1095 nop->isvolatile = op->isvolatile;
1096 nop->isGlobal = op->isGlobal;
1097 nop->isLiteral = op->isLiteral;
1098 nop->noSpilLoc = op->noSpilLoc;
1099 nop->usesDefs = op->usesDefs;
1100 nop->isParm = op->isParm;
1105 nop->operand.symOperand = op->operand.symOperand;
1108 nop->operand.valOperand = op->operand.valOperand;
1111 nop->operand.typeOperand = op->operand.typeOperand;
1118 /*-----------------------------------------------------------------*/
1119 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1120 /*-----------------------------------------------------------------*/
1122 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1124 operand *nop = operandFromOperand (op);
1126 if (nop->type == SYMBOL)
1128 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1129 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1135 /*-----------------------------------------------------------------*/
1136 /* operandFromSymbol - creates an operand from a symbol */
1137 /*-----------------------------------------------------------------*/
1139 operandFromSymbol (symbol * sym)
1144 /* if the symbol's type is a literal */
1145 /* then it is an enumerator type */
1146 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1147 return operandFromValue (valFromType (sym->etype));
1150 sym->key = ++operandKey;
1152 /* if this an implicit variable, means struct/union */
1153 /* member so just return it */
1154 if (sym->implicit || IS_FUNC (sym->type))
1158 op->operand.symOperand = sym;
1160 op->isvolatile = isOperandVolatile (op, TRUE);
1161 op->isGlobal = isOperandGlobal (op);
1165 /* under the following conditions create a
1166 register equivalent for a local symbol */
1167 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1168 (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) &&
1169 options.stackAuto == 0)
1172 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1173 !IS_FUNC (sym->type) && /* not a function */
1174 !sym->_isparm && /* not a parameter */
1175 sym->level && /* is a local variable */
1176 !sym->addrtaken && /* whose address has not been taken */
1177 !sym->reqv && /* does not already have a register euivalence */
1178 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1179 !IS_STATIC (sym->etype) && /* and not declared static */
1180 !sym->islbl && /* not a label */
1181 ok && /* farspace check */
1182 !IS_BITVAR (sym->etype) /* not a bit variable */
1186 /* we will use it after all optimizations
1187 and before liveRange calculation */
1188 sym->reqv = newiTempOperand (sym->type, 0);
1189 sym->reqv->key = sym->key;
1190 OP_SYMBOL (sym->reqv)->key = sym->key;
1191 OP_SYMBOL (sym->reqv)->isreqv = 1;
1192 OP_SYMBOL (sym->reqv)->islocal = 1;
1193 SPIL_LOC (sym->reqv) = sym;
1196 if (!IS_AGGREGATE (sym->type))
1200 op->operand.symOperand = sym;
1203 op->isvolatile = isOperandVolatile (op, TRUE);
1204 op->isGlobal = isOperandGlobal (op);
1205 op->isPtr = IS_PTR (operandType (op));
1206 op->isParm = sym->_isparm;
1211 /* itemp = &[_symbol] */
1213 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1214 IC_LEFT (ic)->type = SYMBOL;
1215 IC_LEFT (ic)->operand.symOperand = sym;
1216 IC_LEFT (ic)->key = sym->key;
1217 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1218 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1219 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1222 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1223 if (IS_ARRAY (sym->type))
1225 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1226 IC_RESULT (ic)->isaddr = 0;
1229 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1231 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1235 return IC_RESULT (ic);
1238 /*-----------------------------------------------------------------*/
1239 /* operandFromValue - creates an operand from value */
1240 /*-----------------------------------------------------------------*/
1242 operandFromValue (value * val)
1246 /* if this is a symbol then do the symbol thing */
1248 return operandFromSymbol (val->sym);
1250 /* this is not a symbol */
1253 op->operand.valOperand = val;
1254 op->isLiteral = isOperandLiteral (op);
1258 /*-----------------------------------------------------------------*/
1259 /* operandFromLink - operand from typeChain */
1260 /*-----------------------------------------------------------------*/
1262 operandFromLink (sym_link * type)
1266 /* operand from sym_link */
1272 op->operand.typeOperand = copyLinkChain (type);
1276 /*-----------------------------------------------------------------*/
1277 /* operandFromLit - makes an operand from a literal value */
1278 /*-----------------------------------------------------------------*/
1280 operandFromLit (float i)
1282 return operandFromValue (valueFromLit (i));
1285 /*-----------------------------------------------------------------*/
1286 /* operandFromAst - creates an operand from an ast */
1287 /*-----------------------------------------------------------------*/
1289 operandFromAst (ast * tree,int lvl)
1295 /* depending on type do */
1299 return ast2iCode (tree,lvl+1);
1303 return operandFromValue (tree->opval.val);
1307 return operandFromLink (tree->opval.lnk);
1311 /* Just to keep the comiler happy */
1312 return (operand *) 0;
1315 /*-----------------------------------------------------------------*/
1316 /* setOperandType - sets the operand's type to the given type */
1317 /*-----------------------------------------------------------------*/
1319 setOperandType (operand * op, sym_link * type)
1321 /* depending on the type of operand */
1326 op->operand.valOperand->etype =
1327 getSpec (op->operand.valOperand->type =
1328 copyLinkChain (type));
1332 if (op->operand.symOperand->isitmp)
1333 op->operand.symOperand->etype =
1334 getSpec (op->operand.symOperand->type =
1335 copyLinkChain (type));
1337 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1338 "attempt to modify type of source");
1342 op->operand.typeOperand = copyLinkChain (type);
1347 /*-----------------------------------------------------------------*/
1348 /* Get size in byte of ptr need to access an array */
1349 /*-----------------------------------------------------------------*/
1351 getArraySizePtr (operand * op)
1353 sym_link *ltype = operandType(op);
1357 int size = getSize(ltype);
1358 return(IS_GENPTR(ltype)?(size-1):size);
1363 sym_link *letype = getSpec(ltype);
1364 switch (PTR_TYPE (SPEC_OCLS (letype)))
1376 return (GPTRSIZE-1);
1385 /*-----------------------------------------------------------------*/
1386 /* perform "usual unary conversions" */
1387 /*-----------------------------------------------------------------*/
1389 usualUnaryConversions (operand * op)
1391 if (IS_INTEGRAL (operandType (op)))
1393 if (getSize (operandType (op)) < INTSIZE)
1396 return geniCodeCast (INTTYPE, op, TRUE);
1402 /*-----------------------------------------------------------------*/
1403 /* perform "usual binary conversions" */
1404 /*-----------------------------------------------------------------*/
1406 usualBinaryConversions (operand ** op1, operand ** op2)
1409 sym_link *rtype = operandType (*op2);
1410 sym_link *ltype = operandType (*op1);
1412 ctype = computeType (ltype, rtype);
1413 *op1 = geniCodeCast (ctype, *op1, TRUE);
1414 *op2 = geniCodeCast (ctype, *op2, TRUE);
1419 /*-----------------------------------------------------------------*/
1420 /* geniCodeValueAtAddress - generate intermeditate code for value */
1422 /*-----------------------------------------------------------------*/
1424 geniCodeRValue (operand * op, bool force)
1427 sym_link *type = operandType (op);
1428 sym_link *etype = getSpec (type);
1430 /* if this is an array & already */
1431 /* an address then return this */
1432 if (IS_AGGREGATE (type) ||
1433 (IS_PTR (type) && !force && !op->isaddr))
1434 return operandFromOperand (op);
1436 /* if this is not an address then must be */
1437 /* rvalue already so return this one */
1441 /* if this is not a temp symbol then */
1442 if (!IS_ITEMP (op) &&
1444 !IN_FARSPACE (SPEC_OCLS (etype)))
1446 op = operandFromOperand (op);
1451 if (IS_SPEC (type) &&
1452 IS_TRUE_SYMOP (op) &&
1453 (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
1455 op = operandFromOperand (op);
1460 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1461 if (IS_PTR (type) && op->isaddr && force)
1464 type = copyLinkChain (type);
1466 IC_RESULT (ic) = newiTempOperand (type, 1);
1467 IC_RESULT (ic)->isaddr = 0;
1469 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1471 /* if the right is a symbol */
1472 if (op->type == SYMBOL)
1473 IC_RESULT (ic)->operand.symOperand->args =
1474 op->operand.symOperand->args;
1477 return IC_RESULT (ic);
1480 /*-----------------------------------------------------------------*/
1481 /* geniCodeCast - changes the value from one type to another */
1482 /*-----------------------------------------------------------------*/
1484 geniCodeCast (sym_link * type, operand * op, bool implicit)
1488 sym_link *opetype = getSpec (optype = operandType (op));
1491 /* one of them has size zero then error */
1492 if (IS_VOID (optype))
1494 werror (E_CAST_ZERO);
1498 /* if the operand is already the desired type then do nothing */
1499 if (checkType (type, optype) == 1)
1502 /* if this is a literal then just change the type & return */
1503 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1504 return operandFromValue (valCastLiteral (type,
1505 operandLitValue (op)));
1507 /* if casting to some pointer type &&
1508 the destination is not a generic pointer
1509 then give a warning : (only for implicit casts) */
1510 if (IS_PTR (optype) && implicit &&
1511 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1514 werror (E_INCOMPAT_CAST);
1515 werror (E_CONTINUE, "from type '");
1516 printTypeChain (optype, stderr);
1517 fprintf (stderr, "' to type '");
1518 printTypeChain (type, stderr);
1519 fprintf (stderr, "'\n");
1522 /* if they are the same size create an assignment */
1523 if (getSize (type) == getSize (optype) &&
1524 !IS_BITFIELD (type) &&
1526 !IS_FLOAT (optype) &&
1527 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1528 (!IS_SPEC (type) && !IS_SPEC (optype))))
1531 ic = newiCode ('=', NULL, op);
1532 IC_RESULT (ic) = newiTempOperand (type, 0);
1533 SPIL_LOC (IC_RESULT (ic)) =
1534 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1535 IC_RESULT (ic)->isaddr = 0;
1539 ic = newiCode (CAST, operandFromLink (type),
1540 geniCodeRValue (op, FALSE));
1542 IC_RESULT (ic) = newiTempOperand (type, 0);
1545 /* preserve the storage class & output class */
1546 /* of the original variable */
1547 restype = getSpec (operandType (IC_RESULT (ic)));
1548 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1549 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1552 return IC_RESULT (ic);
1555 /*-----------------------------------------------------------------*/
1556 /* geniCodeLabel - will create a Label */
1557 /*-----------------------------------------------------------------*/
1559 geniCodeLabel (symbol * label)
1563 ic = newiCodeLabelGoto (LABEL, label);
1567 /*-----------------------------------------------------------------*/
1568 /* geniCodeGoto - will create a Goto */
1569 /*-----------------------------------------------------------------*/
1571 geniCodeGoto (symbol * label)
1575 ic = newiCodeLabelGoto (GOTO, label);
1579 /*-----------------------------------------------------------------*/
1580 /* geniCodeMultiply - gen intermediate code for multiplication */
1581 /*-----------------------------------------------------------------*/
1583 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1590 /* if they are both literal then we know the result */
1591 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1592 return operandFromValue (valMult (left->operand.valOperand,
1593 right->operand.valOperand));
1595 if (IS_LITERAL(retype)) {
1596 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1599 resType = usualBinaryConversions (&left, &right);
1601 rtype = operandType (right);
1602 retype = getSpec (rtype);
1603 ltype = operandType (left);
1604 letype = getSpec (ltype);
1608 SPEC_NOUN(getSpec(resType))=V_INT;
1609 SPEC_SHORT(getSpec(resType))=0;
1612 /* if the right is a literal & power of 2 */
1613 /* then make it a left shift */
1614 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1615 efficient in most cases than 2 bytes result = 2 bytes << literal
1616 if port has 1 byte muldiv */
1617 if (p2 && !IS_FLOAT (letype) &&
1618 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1619 (port->muldiv.native_below == 1)))
1621 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1623 /* LEFT_OP need same size for left and result, */
1624 left = geniCodeCast (resType, left, TRUE);
1625 ltype = operandType (left);
1627 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1631 ic = newiCode ('*', left, right); /* normal multiplication */
1632 /* if the size left or right > 1 then support routine */
1633 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1637 IC_RESULT (ic) = newiTempOperand (resType, 1);
1640 return IC_RESULT (ic);
1643 /*-----------------------------------------------------------------*/
1644 /* geniCodeDivision - gen intermediate code for division */
1645 /*-----------------------------------------------------------------*/
1647 geniCodeDivision (operand * left, operand * right)
1652 sym_link *rtype = operandType (right);
1653 sym_link *retype = getSpec (rtype);
1654 sym_link *ltype = operandType (left);
1655 sym_link *letype = getSpec (ltype);
1657 resType = usualBinaryConversions (&left, &right);
1659 /* if the right is a literal & power of 2 */
1660 /* then make it a right shift */
1661 if (IS_LITERAL (retype) &&
1662 !IS_FLOAT (letype) &&
1663 (p2 = powof2 ((unsigned long)
1664 floatFromVal (right->operand.valOperand))))
1665 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1668 ic = newiCode ('/', left, right); /* normal division */
1669 /* if the size left or right > 1 then support routine */
1670 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1673 IC_RESULT (ic) = newiTempOperand (resType, 0);
1676 return IC_RESULT (ic);
1678 /*-----------------------------------------------------------------*/
1679 /* geniCodeModulus - gen intermediate code for modulus */
1680 /*-----------------------------------------------------------------*/
1682 geniCodeModulus (operand * left, operand * right)
1688 /* if they are both literal then we know the result */
1689 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1690 return operandFromValue (valMod (left->operand.valOperand,
1691 right->operand.valOperand));
1693 resType = usualBinaryConversions (&left, &right);
1695 /* now they are the same size */
1696 ic = newiCode ('%', left, right);
1698 /* if the size left or right > 1 then support routine */
1699 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1701 IC_RESULT (ic) = newiTempOperand (resType, 0);
1704 return IC_RESULT (ic);
1707 /*-----------------------------------------------------------------*/
1708 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1709 /*-----------------------------------------------------------------*/
1711 geniCodePtrPtrSubtract (operand * left, operand * right)
1717 /* if they are both literals then */
1718 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1720 result = operandFromValue (valMinus (left->operand.valOperand,
1721 right->operand.valOperand));
1725 ic = newiCode ('-', left, right);
1727 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1731 return geniCodeDivision (result,
1732 operandFromLit (getSize (ltype->next)));
1735 /*-----------------------------------------------------------------*/
1736 /* geniCodeSubtract - generates code for subtraction */
1737 /*-----------------------------------------------------------------*/
1739 geniCodeSubtract (operand * left, operand * right)
1746 /* if they both pointers then */
1747 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1748 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1749 return geniCodePtrPtrSubtract (left, right);
1751 /* if they are both literal then we know the result */
1752 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1753 && left->isLiteral && right->isLiteral)
1754 return operandFromValue (valMinus (left->operand.valOperand,
1755 right->operand.valOperand));
1757 /* if left is an array or pointer */
1758 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1760 isarray = left->isaddr;
1761 right = geniCodeMultiply (right,
1762 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1763 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1766 { /* make them the same size */
1767 resType = usualBinaryConversions (&left, &right);
1770 ic = newiCode ('-', left, right);
1772 IC_RESULT (ic) = newiTempOperand (resType, 1);
1773 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1775 /* if left or right is a float */
1776 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1780 return IC_RESULT (ic);
1783 /*-----------------------------------------------------------------*/
1784 /* geniCodeAdd - generates iCode for addition */
1785 /*-----------------------------------------------------------------*/
1787 geniCodeAdd (operand * left, operand * right,int lvl)
1795 /* if left is an array then array access */
1796 if (IS_ARRAY (ltype))
1797 return geniCodeArray (left, right,lvl);
1799 /* if the right side is LITERAL zero */
1800 /* return the left side */
1801 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1804 /* if left is literal zero return right */
1805 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1808 /* if left is an array or pointer then size */
1811 isarray = left->isaddr;
1812 // there is no need to multiply with 1
1813 if (getSize(ltype->next)!=1) {
1814 size = operandFromLit (getSize (ltype->next));
1815 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1817 resType = copyLinkChain (ltype);
1820 { /* make them the same size */
1821 resType = usualBinaryConversions (&left, &right);
1824 /* if they are both literals then we know */
1825 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1826 && left->isLiteral && right->isLiteral)
1827 return operandFromValue (valPlus (valFromType (letype),
1828 valFromType (retype)));
1830 ic = newiCode ('+', left, right);
1832 IC_RESULT (ic) = newiTempOperand (resType, 1);
1833 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1835 /* if left or right is a float then support
1837 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1842 return IC_RESULT (ic);
1846 /*-----------------------------------------------------------------*/
1847 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1848 /*-----------------------------------------------------------------*/
1850 aggrToPtr (sym_link * type, bool force)
1856 if (IS_PTR (type) && !force)
1859 etype = getSpec (type);
1863 /* if the output class is generic */
1864 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1865 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1867 /* if the variable was declared a constant */
1868 /* then the pointer points to a constant */
1869 if (IS_CONSTANT (etype))
1870 DCL_PTR_CONST (ptype) = 1;
1872 /* the variable was volatile then pointer to volatile */
1873 if (IS_VOLATILE (etype))
1874 DCL_PTR_VOLATILE (ptype) = 1;
1878 /*-----------------------------------------------------------------*/
1879 /* geniCodeArray2Ptr - array to pointer */
1880 /*-----------------------------------------------------------------*/
1882 geniCodeArray2Ptr (operand * op)
1884 sym_link *optype = operandType (op);
1885 sym_link *opetype = getSpec (optype);
1887 /* set the pointer depending on the storage class */
1888 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1889 DCL_PTR_CONST (optype) = port->mem.code_ro;
1892 /* if the variable was declared a constant */
1893 /* then the pointer points to a constant */
1894 if (IS_CONSTANT (opetype))
1895 DCL_PTR_CONST (optype) = 1;
1897 /* the variable was volatile then pointer to volatile */
1898 if (IS_VOLATILE (opetype))
1899 DCL_PTR_VOLATILE (optype) = 1;
1905 /*-----------------------------------------------------------------*/
1906 /* geniCodeArray - array access */
1907 /*-----------------------------------------------------------------*/
1909 geniCodeArray (operand * left, operand * right,int lvl)
1912 sym_link *ltype = operandType (left);
1916 if (IS_PTR (ltype->next) && left->isaddr)
1918 left = geniCodeRValue (left, FALSE);
1920 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
1923 right = geniCodeMultiply (right,
1924 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1926 /* we can check for limits here */
1927 if (isOperandLiteral (right) &&
1930 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
1932 werror (E_ARRAY_BOUND);
1933 right = operandFromLit (0);
1936 ic = newiCode ('+', left, right);
1938 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
1939 !IS_AGGREGATE (ltype->next) &&
1940 !IS_PTR (ltype->next))
1941 ? ltype : ltype->next), 0);
1943 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
1945 return IC_RESULT (ic);
1948 /*-----------------------------------------------------------------*/
1949 /* geniCodeStruct - generates intermediate code for structres */
1950 /*-----------------------------------------------------------------*/
1952 geniCodeStruct (operand * left, operand * right, bool islval)
1955 sym_link *type = operandType (left);
1956 sym_link *etype = getSpec (type);
1958 symbol *element = getStructElement (SPEC_STRUCT (etype),
1959 right->operand.symOperand);
1961 /* add the offset */
1962 ic = newiCode ('+', left, operandFromLit (element->offset));
1964 IC_RESULT (ic) = newiTempOperand (element->type, 0);
1966 /* preserve the storage & output class of the struct */
1967 /* as well as the volatile attribute */
1968 retype = getSpec (operandType (IC_RESULT (ic)));
1969 SPEC_SCLS (retype) = SPEC_SCLS (etype);
1970 SPEC_OCLS (retype) = SPEC_OCLS (etype);
1971 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
1973 if (IS_PTR (element->type))
1974 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1976 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
1980 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
1983 /*-----------------------------------------------------------------*/
1984 /* geniCodePostInc - generate int code for Post increment */
1985 /*-----------------------------------------------------------------*/
1987 geniCodePostInc (operand * op)
1991 sym_link *optype = operandType (op);
1993 operand *rv = (IS_ITEMP (op) ?
1994 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
1996 sym_link *rvtype = operandType (rv);
1999 /* if this is not an address we have trouble */
2002 werror (E_LVALUE_REQUIRED, "++");
2006 rOp = newiTempOperand (rvtype, 0);
2012 geniCodeAssign (rOp, rv, 0);
2014 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2015 if (IS_FLOAT (rvtype))
2016 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2018 ic = newiCode ('+', rv, operandFromLit (size));
2020 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2023 geniCodeAssign (op, result, 0);
2029 /*-----------------------------------------------------------------*/
2030 /* geniCodePreInc - generate code for preIncrement */
2031 /*-----------------------------------------------------------------*/
2033 geniCodePreInc (operand * op)
2036 sym_link *optype = operandType (op);
2037 operand *rop = (IS_ITEMP (op) ?
2038 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2040 sym_link *roptype = operandType (rop);
2046 werror (E_LVALUE_REQUIRED, "++");
2051 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2052 if (IS_FLOAT (roptype))
2053 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2055 ic = newiCode ('+', rop, operandFromLit (size));
2056 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2060 return geniCodeAssign (op, result, 0);
2063 /*-----------------------------------------------------------------*/
2064 /* geniCodePostDec - generates code for Post decrement */
2065 /*-----------------------------------------------------------------*/
2067 geniCodePostDec (operand * op)
2071 sym_link *optype = operandType (op);
2073 operand *rv = (IS_ITEMP (op) ?
2074 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2076 sym_link *rvtype = operandType (rv);
2079 /* if this is not an address we have trouble */
2082 werror (E_LVALUE_REQUIRED, "++");
2086 rOp = newiTempOperand (rvtype, 0);
2092 geniCodeAssign (rOp, rv, 0);
2094 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2095 if (IS_FLOAT (rvtype))
2096 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2098 ic = newiCode ('-', rv, operandFromLit (size));
2100 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2103 geniCodeAssign (op, result, 0);
2109 /*-----------------------------------------------------------------*/
2110 /* geniCodePreDec - generate code for pre decrement */
2111 /*-----------------------------------------------------------------*/
2113 geniCodePreDec (operand * op)
2116 sym_link *optype = operandType (op);
2117 operand *rop = (IS_ITEMP (op) ?
2118 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2120 sym_link *roptype = operandType (rop);
2126 werror (E_LVALUE_REQUIRED, "++");
2131 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2132 if (IS_FLOAT (roptype))
2133 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2135 ic = newiCode ('-', rop, operandFromLit (size));
2136 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2140 return geniCodeAssign (op, result, 0);
2144 /*-----------------------------------------------------------------*/
2145 /* geniCodeBitwise - gen int code for bitWise operators */
2146 /*-----------------------------------------------------------------*/
2148 geniCodeBitwise (operand * left, operand * right,
2149 int oper, sym_link * resType)
2153 left = geniCodeCast (resType, left, TRUE);
2154 right = geniCodeCast (resType, right, TRUE);
2156 ic = newiCode (oper, left, right);
2157 IC_RESULT (ic) = newiTempOperand (resType, 0);
2160 return IC_RESULT (ic);
2163 /*-----------------------------------------------------------------*/
2164 /* geniCodeAddressOf - gens icode for '&' address of operator */
2165 /*-----------------------------------------------------------------*/
2167 geniCodeAddressOf (operand * op)
2171 sym_link *optype = operandType (op);
2172 sym_link *opetype = getSpec (optype);
2174 /* lvalue check already done in decorateType */
2175 /* this must be a lvalue */
2176 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2177 /* werror (E_LVALUE_REQUIRED,"&"); */
2182 p->class = DECLARATOR;
2184 /* set the pointer depending on the storage class */
2185 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2186 DCL_PTR_CONST (p) = port->mem.code_ro;
2188 /* make sure we preserve the const & volatile */
2189 if (IS_CONSTANT (opetype))
2190 DCL_PTR_CONST (p) = 1;
2192 if (IS_VOLATILE (opetype))
2193 DCL_PTR_VOLATILE (p) = 1;
2195 p->next = copyLinkChain (optype);
2197 /* if already a temp */
2200 setOperandType (op, p);
2205 /* other wise make this of the type coming in */
2206 ic = newiCode (ADDRESS_OF, op, NULL);
2207 IC_RESULT (ic) = newiTempOperand (p, 1);
2208 IC_RESULT (ic)->isaddr = 0;
2210 return IC_RESULT (ic);
2212 /*-----------------------------------------------------------------*/
2213 /* setOClass - sets the output class depending on the pointer type */
2214 /*-----------------------------------------------------------------*/
2216 setOClass (sym_link * ptr, sym_link * spec)
2218 switch (DCL_TYPE (ptr))
2221 SPEC_OCLS (spec) = data;
2225 SPEC_OCLS (spec) = generic;
2229 SPEC_OCLS (spec) = xdata;
2233 SPEC_OCLS (spec) = code;
2237 SPEC_OCLS (spec) = idata;
2241 SPEC_OCLS (spec) = xstack;
2245 SPEC_OCLS (spec) = eeprom;
2254 /*-----------------------------------------------------------------*/
2255 /* geniCodeDerefPtr - dereference pointer with '*' */
2256 /*-----------------------------------------------------------------*/
2258 geniCodeDerefPtr (operand * op,int lvl)
2260 sym_link *rtype, *retype;
2261 sym_link *optype = operandType (op);
2263 /* if this is a pointer then generate the rvalue */
2264 if (IS_PTR (optype))
2266 if (IS_TRUE_SYMOP (op))
2269 op = geniCodeRValue (op, TRUE);
2272 op = geniCodeRValue (op, TRUE);
2275 /* now get rid of the pointer part */
2276 if (isLvaluereq(lvl) && IS_ITEMP (op))
2278 retype = getSpec (rtype = copyLinkChain (optype));
2282 retype = getSpec (rtype = copyLinkChain (optype->next));
2285 /* if this is a pointer then outputclass needs 2b updated */
2286 if (IS_PTR (optype))
2287 setOClass (optype, retype);
2289 op->isGptr = IS_GENPTR (optype);
2291 /* if the pointer was declared as a constant */
2292 /* then we cannot allow assignment to the derefed */
2293 if (IS_PTR_CONST (optype))
2294 SPEC_CONST (retype) = 1;
2296 op->isaddr = (IS_PTR (rtype) ||
2297 IS_STRUCT (rtype) ||
2302 if (!isLvaluereq(lvl))
2303 op = geniCodeRValue (op, TRUE);
2305 setOperandType (op, rtype);
2310 /*-----------------------------------------------------------------*/
2311 /* geniCodeUnaryMinus - does a unary minus of the operand */
2312 /*-----------------------------------------------------------------*/
2314 geniCodeUnaryMinus (operand * op)
2317 sym_link *optype = operandType (op);
2319 if (IS_LITERAL (optype))
2320 return operandFromLit (-floatFromVal (op->operand.valOperand));
2322 ic = newiCode (UNARYMINUS, op, NULL);
2323 IC_RESULT (ic) = newiTempOperand (optype, 0);
2325 return IC_RESULT (ic);
2328 /*-----------------------------------------------------------------*/
2329 /* geniCodeLeftShift - gen i code for left shift */
2330 /*-----------------------------------------------------------------*/
2332 geniCodeLeftShift (operand * left, operand * right)
2336 ic = newiCode (LEFT_OP, left, right);
2337 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2339 return IC_RESULT (ic);
2342 /*-----------------------------------------------------------------*/
2343 /* geniCodeRightShift - gen i code for right shift */
2344 /*-----------------------------------------------------------------*/
2346 geniCodeRightShift (operand * left, operand * right)
2350 ic = newiCode (RIGHT_OP, left, right);
2351 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2353 return IC_RESULT (ic);
2356 #if defined(__BORLANDC__) || defined(_MSC_VER)
2357 #define LONG_LONG __int64
2359 #define LONG_LONG long long
2362 /*-----------------------------------------------------------------*/
2363 /* geniCodeLogic- logic code */
2364 /*-----------------------------------------------------------------*/
2366 geniCodeLogic (operand * left, operand * right, int op)
2370 sym_link *rtype = operandType (right);
2371 sym_link *ltype = operandType (left);
2373 /* left is integral type and right is literal then
2374 check if the literal value is within bounds */
2375 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2377 int nbits = bitsForType (ltype);
2378 long v = operandLitValue (right);
2380 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2381 werror (W_CONST_RANGE, " compare operation ");
2384 ctype = usualBinaryConversions (&left, &right);
2386 ic = newiCode (op, left, right);
2387 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2389 /* if comparing float
2390 and not a '==' || '!=' || '&&' || '||' (these
2392 if (IS_FLOAT(ctype) &&
2400 return IC_RESULT (ic);
2403 /*-----------------------------------------------------------------*/
2404 /* geniCodeUnary - for a a generic unary operation */
2405 /*-----------------------------------------------------------------*/
2407 geniCodeUnary (operand * op, int oper)
2409 iCode *ic = newiCode (oper, op, NULL);
2411 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2413 return IC_RESULT (ic);
2416 /*-----------------------------------------------------------------*/
2417 /* geniCodeConditional - geniCode for '?' ':' operation */
2418 /*-----------------------------------------------------------------*/
2420 geniCodeConditional (ast * tree,int lvl)
2423 symbol *falseLabel = newiTempLabel (NULL);
2424 symbol *exitLabel = newiTempLabel (NULL);
2425 operand *cond = ast2iCode (tree->left,lvl+1);
2426 operand *true, *false, *result;
2428 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2432 true = ast2iCode (tree->right->left,lvl+1);
2434 /* move the value to a new Operand */
2435 result = newiTempOperand (operandType (true), 0);
2436 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2438 /* generate an unconditional goto */
2439 geniCodeGoto (exitLabel);
2441 /* now for the right side */
2442 geniCodeLabel (falseLabel);
2444 false = ast2iCode (tree->right->right,lvl+1);
2445 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2447 /* create the exit label */
2448 geniCodeLabel (exitLabel);
2453 /*-----------------------------------------------------------------*/
2454 /* geniCodeAssign - generate code for assignment */
2455 /*-----------------------------------------------------------------*/
2457 geniCodeAssign (operand * left, operand * right, int nosupdate)
2460 sym_link *ltype = operandType (left);
2461 sym_link *rtype = operandType (right);
2463 if (!left->isaddr && !IS_ITEMP (left))
2465 werror (E_LVALUE_REQUIRED, "assignment");
2469 /* left is integral type and right is literal then
2470 check if the literal value is within bounds */
2471 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2473 int nbits = bitsForType (ltype);
2474 long v = operandLitValue (right);
2476 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2477 werror (W_CONST_RANGE, " = operation");
2480 /* if the left & right type don't exactly match */
2481 /* if pointer set then make sure the check is
2482 done with the type & not the pointer */
2483 /* then cast rights type to left */
2485 /* first check the type for pointer assignement */
2486 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2487 checkType (ltype, rtype) < 0)
2489 if (checkType (ltype->next, rtype) < 0)
2490 right = geniCodeCast (ltype->next, right, TRUE);
2492 else if (checkType (ltype, rtype) < 0)
2493 right = geniCodeCast (ltype, right, TRUE);
2495 /* if left is a true symbol & ! volatile
2496 create an assignment to temporary for
2497 the right & then assign this temporary
2498 to the symbol this is SSA . isn't it simple
2499 and folks have published mountains of paper on it */
2500 if (IS_TRUE_SYMOP (left) &&
2501 !isOperandVolatile (left, FALSE) &&
2502 isOperandGlobal (left))
2506 if (IS_TRUE_SYMOP (right))
2507 sym = OP_SYMBOL (right);
2508 ic = newiCode ('=', NULL, right);
2509 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2510 SPIL_LOC (right) = sym;
2514 ic = newiCode ('=', NULL, right);
2515 IC_RESULT (ic) = left;
2518 /* if left isgptr flag is set then support
2519 routine will be required */
2523 ic->nosupdate = nosupdate;
2527 /*-----------------------------------------------------------------*/
2528 /* geniCodeSEParms - generate code for side effecting fcalls */
2529 /*-----------------------------------------------------------------*/
2531 geniCodeSEParms (ast * parms,int lvl)
2536 if (parms->type == EX_OP && parms->opval.op == PARAM)
2538 geniCodeSEParms (parms->left,lvl);
2539 geniCodeSEParms (parms->right,lvl);
2543 /* hack don't like this but too lazy to think of
2545 if (IS_ADDRESS_OF_OP (parms))
2546 parms->left->lvalue = 1;
2548 if (IS_CAST_OP (parms) &&
2549 IS_PTR (parms->ftype) &&
2550 IS_ADDRESS_OF_OP (parms->right))
2551 parms->right->left->lvalue = 1;
2553 parms->opval.oprnd =
2554 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2556 parms->type = EX_OPERAND;
2559 /*-----------------------------------------------------------------*/
2560 /* geniCodeParms - generates parameters */
2561 /*-----------------------------------------------------------------*/
2563 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2571 /* if this is a param node then do the left & right */
2572 if (parms->type == EX_OP && parms->opval.op == PARAM)
2574 geniCodeParms (parms->left, stack, fetype, func,lvl);
2575 geniCodeParms (parms->right, stack, fetype, func,lvl);
2579 /* get the parameter value */
2580 if (parms->type == EX_OPERAND)
2581 pval = parms->opval.oprnd;
2584 /* maybe this else should go away ?? */
2585 /* hack don't like this but too lazy to think of
2587 if (IS_ADDRESS_OF_OP (parms))
2588 parms->left->lvalue = 1;
2590 if (IS_CAST_OP (parms) &&
2591 IS_PTR (parms->ftype) &&
2592 IS_ADDRESS_OF_OP (parms->right))
2593 parms->right->left->lvalue = 1;
2595 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2598 /* if register parm then make it a send */
2599 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2600 IS_REGPARM (parms->etype)) && !func->hasVargs)
2602 ic = newiCode (SEND, pval, NULL);
2607 /* now decide whether to push or assign */
2608 if (!(options.stackAuto || IS_RENT (fetype)))
2612 operand *top = operandFromSymbol (parms->argSym);
2613 geniCodeAssign (top, pval, 1);
2617 sym_link *p = operandType (pval);
2619 ic = newiCode (IPUSH, pval, NULL);
2621 /* update the stack adjustment */
2622 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2629 /*-----------------------------------------------------------------*/
2630 /* geniCodeCall - generates temp code for calling */
2631 /*-----------------------------------------------------------------*/
2633 geniCodeCall (operand * left, ast * parms,int lvl)
2637 sym_link *type, *etype;
2640 /* take care of parameters with side-effecting
2641 function calls in them, this is required to take care
2642 of overlaying function parameters */
2643 geniCodeSEParms (parms,lvl);
2645 /* first the parameters */
2646 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2648 /* now call : if symbol then pcall */
2649 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2650 ic = newiCode (PCALL, left, NULL);
2652 ic = newiCode (CALL, left, NULL);
2654 IC_ARGS (ic) = left->operand.symOperand->args;
2655 type = copyLinkChain (operandType (left)->next);
2656 etype = getSpec (type);
2657 SPEC_EXTR (etype) = 0;
2658 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2662 /* stack adjustment after call */
2663 ic->parmBytes = stack;
2668 /*-----------------------------------------------------------------*/
2669 /* geniCodeReceive - generate intermediate code for "receive" */
2670 /*-----------------------------------------------------------------*/
2672 geniCodeReceive (value * args)
2674 /* for all arguments that are passed in registers */
2678 if (IS_REGPARM (args->etype))
2680 operand *opr = operandFromValue (args);
2682 symbol *sym = OP_SYMBOL (opr);
2685 /* we will use it after all optimizations
2686 and before liveRange calculation */
2687 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2690 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2691 options.stackAuto == 0 &&
2697 opl = newiTempOperand (args->type, 0);
2699 sym->reqv->key = sym->key;
2700 OP_SYMBOL (sym->reqv)->key = sym->key;
2701 OP_SYMBOL (sym->reqv)->isreqv = 1;
2702 OP_SYMBOL (sym->reqv)->islocal = 0;
2703 SPIL_LOC (sym->reqv) = sym;
2707 ic = newiCode (RECEIVE, NULL, NULL);
2708 currFunc->recvSize = getSize (sym->etype);
2709 IC_RESULT (ic) = opr;
2717 /*-----------------------------------------------------------------*/
2718 /* geniCodeFunctionBody - create the function body */
2719 /*-----------------------------------------------------------------*/
2721 geniCodeFunctionBody (ast * tree,int lvl)
2728 /* reset the auto generation */
2734 func = ast2iCode (tree->left,lvl+1);
2735 fetype = getSpec (operandType (func));
2737 savelineno = lineno;
2738 lineno = OP_SYMBOL (func)->lineDef;
2739 /* create an entry label */
2740 geniCodeLabel (entryLabel);
2741 lineno = savelineno;
2743 /* create a proc icode */
2744 ic = newiCode (FUNCTION, func, NULL);
2745 /* if the function has parmas then */
2746 /* save the parameters information */
2747 ic->argLabel.args = tree->values.args;
2748 ic->lineno = OP_SYMBOL (func)->lineDef;
2752 /* for all parameters that are passed
2753 on registers add a "receive" */
2754 geniCodeReceive (tree->values.args);
2756 /* generate code for the body */
2757 ast2iCode (tree->right,lvl+1);
2759 /* create a label for return */
2760 geniCodeLabel (returnLabel);
2762 /* now generate the end proc */
2763 ic = newiCode (ENDFUNCTION, func, NULL);
2768 /*-----------------------------------------------------------------*/
2769 /* geniCodeReturn - gen icode for 'return' statement */
2770 /*-----------------------------------------------------------------*/
2772 geniCodeReturn (operand * op)
2776 /* if the operand is present force an rvalue */
2778 op = geniCodeRValue (op, FALSE);
2780 ic = newiCode (RETURN, op, NULL);
2784 /*-----------------------------------------------------------------*/
2785 /* geniCodeIfx - generates code for extended if statement */
2786 /*-----------------------------------------------------------------*/
2788 geniCodeIfx (ast * tree,int lvl)
2791 operand *condition = ast2iCode (tree->left,lvl+1);
2794 /* if condition is null then exit */
2798 condition = geniCodeRValue (condition, FALSE);
2800 cetype = getSpec (operandType (condition));
2801 /* if the condition is a literal */
2802 if (IS_LITERAL (cetype))
2804 if (floatFromVal (condition->operand.valOperand))
2806 if (tree->trueLabel)
2807 geniCodeGoto (tree->trueLabel);
2813 if (tree->falseLabel)
2814 geniCodeGoto (tree->falseLabel);
2821 if (tree->trueLabel)
2823 ic = newiCodeCondition (condition,
2828 if (tree->falseLabel)
2829 geniCodeGoto (tree->falseLabel);
2833 ic = newiCodeCondition (condition,
2840 ast2iCode (tree->right,lvl+1);
2843 /*-----------------------------------------------------------------*/
2844 /* geniCodeJumpTable - tries to create a jump table for switch */
2845 /*-----------------------------------------------------------------*/
2847 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2849 int min = 0, max = 0, t, cnt = 0;
2856 if (!tree || !caseVals)
2859 /* the criteria for creating a jump table is */
2860 /* all integer numbers between the maximum & minimum must */
2861 /* be present , the maximum value should not exceed 255 */
2862 min = max = (int) floatFromVal (vch = caseVals);
2863 sprintf (buffer, "_case_%d_%d",
2864 tree->values.switchVals.swNum,
2866 addSet (&labels, newiTempLabel (buffer));
2868 /* if there is only one case value then no need */
2869 if (!(vch = vch->next))
2874 if (((t = (int) floatFromVal (vch)) - max) != 1)
2876 sprintf (buffer, "_case_%d_%d",
2877 tree->values.switchVals.swNum,
2879 addSet (&labels, newiTempLabel (buffer));
2885 /* if the number of case statements <= 2 then */
2886 /* it is not economical to create the jump table */
2887 /* since two compares are needed for boundary conditions */
2888 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2891 if (tree->values.switchVals.swDefault)
2892 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2894 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2896 falseLabel = newiTempLabel (buffer);
2898 /* so we can create a jumptable */
2899 /* first we rule out the boundary conditions */
2900 /* if only optimization says so */
2901 if (!optimize.noJTabBoundary)
2903 sym_link *cetype = getSpec (operandType (cond));
2904 /* no need to check the lower bound if
2905 the condition is unsigned & minimum value is zero */
2906 if (!(min == 0 && SPEC_USIGN (cetype)))
2908 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2909 ic = newiCodeCondition (boundary, falseLabel, NULL);
2913 /* now for upper bounds */
2914 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
2915 ic = newiCodeCondition (boundary, falseLabel, NULL);
2919 /* if the min is not zero then we no make it zero */
2922 cond = geniCodeSubtract (cond, operandFromLit (min));
2923 setOperandType (cond, UCHARTYPE);
2926 /* now create the jumptable */
2927 ic = newiCode (JUMPTABLE, NULL, NULL);
2928 IC_JTCOND (ic) = cond;
2929 IC_JTLABELS (ic) = labels;
2934 /*-----------------------------------------------------------------*/
2935 /* geniCodeSwitch - changes a switch to a if statement */
2936 /*-----------------------------------------------------------------*/
2938 geniCodeSwitch (ast * tree,int lvl)
2941 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
2942 value *caseVals = tree->values.switchVals.swVals;
2943 symbol *trueLabel, *falseLabel;
2945 /* if we can make this a jump table */
2946 if (geniCodeJumpTable (cond, caseVals, tree))
2947 goto jumpTable; /* no need for the comparison */
2949 /* for the cases defined do */
2953 operand *compare = geniCodeLogic (cond,
2954 operandFromValue (caseVals),
2957 sprintf (buffer, "_case_%d_%d",
2958 tree->values.switchVals.swNum,
2959 (int) floatFromVal (caseVals));
2960 trueLabel = newiTempLabel (buffer);
2962 ic = newiCodeCondition (compare, trueLabel, NULL);
2964 caseVals = caseVals->next;
2969 /* if default is present then goto break else break */
2970 if (tree->values.switchVals.swDefault)
2971 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2973 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2975 falseLabel = newiTempLabel (buffer);
2976 geniCodeGoto (falseLabel);
2979 ast2iCode (tree->right,lvl+1);
2982 /*-----------------------------------------------------------------*/
2983 /* geniCodeInline - intermediate code for inline assembler */
2984 /*-----------------------------------------------------------------*/
2986 geniCodeInline (ast * tree)
2990 ic = newiCode (INLINEASM, NULL, NULL);
2991 IC_INLINE (ic) = tree->values.inlineasm;
2995 /*-----------------------------------------------------------------*/
2996 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
2997 /* particular case. Ie : assigning or dereferencing array or ptr */
2998 /*-----------------------------------------------------------------*/
2999 set * lvaluereqSet = NULL;
3000 typedef struct lvalItem
3007 /*-----------------------------------------------------------------*/
3008 /* addLvaluereq - add a flag for lvalreq for current ast level */
3009 /*-----------------------------------------------------------------*/
3010 void addLvaluereq(int lvl)
3012 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3015 addSetHead(&lvaluereqSet,lpItem);
3018 /*-----------------------------------------------------------------*/
3019 /* delLvaluereq - del a flag for lvalreq for current ast level */
3020 /*-----------------------------------------------------------------*/
3024 lpItem = getSet(&lvaluereqSet);
3025 if(lpItem) free(lpItem);
3027 /*-----------------------------------------------------------------*/
3028 /* clearLvaluereq - clear lvalreq flag */
3029 /*-----------------------------------------------------------------*/
3030 void clearLvaluereq()
3033 lpItem = peekSet(lvaluereqSet);
3034 if(lpItem) lpItem->req = 0;
3036 /*-----------------------------------------------------------------*/
3037 /* getLvaluereq - get the last lvalreq level */
3038 /*-----------------------------------------------------------------*/
3039 int getLvaluereqLvl()
3042 lpItem = peekSet(lvaluereqSet);
3043 if(lpItem) return lpItem->lvl;
3046 /*-----------------------------------------------------------------*/
3047 /* isLvaluereq - is lvalreq valid for this level ? */
3048 /*-----------------------------------------------------------------*/
3049 int isLvaluereq(int lvl)
3052 lpItem = peekSet(lvaluereqSet);
3053 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3057 /*-----------------------------------------------------------------*/
3058 /* ast2iCode - creates an icodeList from an ast */
3059 /*-----------------------------------------------------------------*/
3061 ast2iCode (ast * tree,int lvl)
3063 operand *left = NULL;
3064 operand *right = NULL;
3067 /* set the global variables for filename & line number */
3069 filename = tree->filename;
3071 lineno = tree->lineno;
3073 block = tree->block;
3075 scopeLevel = tree->level;
3077 if (tree->type == EX_VALUE)
3078 return operandFromValue (tree->opval.val);
3080 if (tree->type == EX_LINK)
3081 return operandFromLink (tree->opval.lnk);
3083 /* if we find a nullop */
3084 if (tree->type == EX_OP &&
3085 (tree->opval.op == NULLOP ||
3086 tree->opval.op == BLOCK))
3088 ast2iCode (tree->left,lvl+1);
3089 ast2iCode (tree->right,lvl+1);
3093 /* special cases for not evaluating */
3094 if (tree->opval.op != ':' &&
3095 tree->opval.op != '?' &&
3096 tree->opval.op != CALL &&
3097 tree->opval.op != IFX &&
3098 tree->opval.op != LABEL &&
3099 tree->opval.op != GOTO &&
3100 tree->opval.op != SWITCH &&
3101 tree->opval.op != FUNCTION &&
3102 tree->opval.op != INLINEASM)
3105 if (IS_ASSIGN_OP (tree->opval.op) ||
3106 IS_DEREF_OP (tree) ||
3107 (tree->opval.op == '&' && !tree->right) ||
3108 tree->opval.op == PTR_OP)
3111 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3112 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3115 left = operandFromAst (tree->left,lvl);
3117 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3118 left = geniCodeRValue (left, TRUE);
3122 left = operandFromAst (tree->left,lvl);
3124 if (tree->opval.op == INC_OP ||
3125 tree->opval.op == DEC_OP)
3128 right = operandFromAst (tree->right,lvl);
3133 right = operandFromAst (tree->right,lvl);
3137 /* now depending on the type of operand */
3138 /* this will be a biggy */
3139 switch (tree->opval.op)
3142 case '[': /* array operation */
3144 sym_link *ltype = operandType (left);
3145 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3146 right = geniCodeRValue (right, TRUE);
3149 return geniCodeArray (left, right,lvl);
3151 case '.': /* structure dereference */
3152 if (IS_PTR (operandType (left)))
3153 left = geniCodeRValue (left, TRUE);
3155 left = geniCodeRValue (left, FALSE);
3157 return geniCodeStruct (left, right, tree->lvalue);
3159 case PTR_OP: /* structure pointer dereference */
3162 pType = operandType (left);
3163 left = geniCodeRValue (left, TRUE);
3165 setOClass (pType, getSpec (operandType (left)));
3168 return geniCodeStruct (left, right, tree->lvalue);
3170 case INC_OP: /* increment operator */
3172 return geniCodePostInc (left);
3174 return geniCodePreInc (right);
3176 case DEC_OP: /* decrement operator */
3178 return geniCodePostDec (left);
3180 return geniCodePreDec (right);
3182 case '&': /* bitwise and or address of operator */
3184 { /* this is a bitwise operator */
3185 left = geniCodeRValue (left, FALSE);
3186 right = geniCodeRValue (right, FALSE);
3187 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3190 return geniCodeAddressOf (left);
3192 case '|': /* bitwise or & xor */
3194 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3195 geniCodeRValue (right, FALSE),
3200 return geniCodeDivision (geniCodeRValue (left, FALSE),
3201 geniCodeRValue (right, FALSE));
3204 return geniCodeModulus (geniCodeRValue (left, FALSE),
3205 geniCodeRValue (right, FALSE));
3208 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3209 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3211 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3215 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3216 geniCodeRValue (right, FALSE));
3218 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3222 return geniCodeAdd (geniCodeRValue (left, FALSE),
3223 geniCodeRValue (right, FALSE),lvl);
3225 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3228 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3229 geniCodeRValue (right, FALSE));
3232 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3233 geniCodeRValue (right, FALSE));
3235 return geniCodeCast (operandType (left),
3236 geniCodeRValue (right, FALSE), FALSE);
3242 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3246 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3247 setOperandType (op, UCHARTYPE);
3258 return geniCodeLogic (geniCodeRValue (left, FALSE),
3259 geniCodeRValue (right, FALSE),
3262 return geniCodeConditional (tree,lvl);
3265 return operandFromLit (getSize (tree->right->ftype));
3269 sym_link *rtype = operandType (right);
3270 sym_link *ltype = operandType (left);
3271 if (IS_PTR (rtype) && IS_ITEMP (right)
3272 && right->isaddr && checkType (rtype->next, ltype) == 1)
3273 right = geniCodeRValue (right, TRUE);
3275 right = geniCodeRValue (right, FALSE);
3277 geniCodeAssign (left, right, 0);
3282 geniCodeAssign (left,
3283 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3285 geniCodeRValue (right, FALSE),FALSE), 0);
3289 geniCodeAssign (left,
3290 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3292 geniCodeRValue (right, FALSE)), 0);
3295 geniCodeAssign (left,
3296 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3298 geniCodeRValue (right, FALSE)), 0);
3301 sym_link *rtype = operandType (right);
3302 sym_link *ltype = operandType (left);
3303 if (IS_PTR (rtype) && IS_ITEMP (right)
3304 && right->isaddr && checkType (rtype->next, ltype) == 1)
3305 right = geniCodeRValue (right, TRUE);
3307 right = geniCodeRValue (right, FALSE);
3310 return geniCodeAssign (left,
3311 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
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)
3322 right = geniCodeRValue (right, TRUE);
3326 right = geniCodeRValue (right, FALSE);
3329 geniCodeAssign (left,
3330 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3336 geniCodeAssign (left,
3337 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3339 geniCodeRValue (right, FALSE)), 0);
3342 geniCodeAssign (left,
3343 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3345 geniCodeRValue (right, FALSE)), 0);
3348 geniCodeAssign (left,
3349 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3351 geniCodeRValue (right, FALSE),
3353 operandType (left)), 0);
3356 geniCodeAssign (left,
3357 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3359 geniCodeRValue (right, FALSE),
3361 operandType (left)), 0);
3364 geniCodeAssign (left,
3365 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3367 geniCodeRValue (right, FALSE),
3369 operandType (left)), 0);
3371 return geniCodeRValue (right, FALSE);
3374 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3377 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3378 return ast2iCode (tree->right,lvl+1);
3381 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3382 return ast2iCode (tree->right,lvl+1);
3385 geniCodeFunctionBody (tree,lvl);
3389 geniCodeReturn (right);
3393 geniCodeIfx (tree,lvl);
3397 geniCodeSwitch (tree,lvl);
3401 geniCodeInline (tree);
3408 /*-----------------------------------------------------------------*/
3409 /* reverseICChain - gets from the list and creates a linkedlist */
3410 /*-----------------------------------------------------------------*/
3417 while ((loop = getSet (&iCodeChain)))
3429 /*-----------------------------------------------------------------*/
3430 /* iCodeFromAst - given an ast will convert it to iCode */
3431 /*-----------------------------------------------------------------*/
3433 iCodeFromAst (ast * tree)
3435 returnLabel = newiTempLabel ("_return");
3436 entryLabel = newiTempLabel ("_entry");
3438 return reverseiCChain ();