1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
28 /*-----------------------------------------------------------------*/
29 /* global variables */
31 set *iCodeChain = NULL;
41 symbol *returnLabel; /* function return label */
42 symbol *entryLabel; /* function entry label */
43 /*-----------------------------------------------------------------*/
44 /* forward definition of some functions */
45 operand *geniCodeDivision (operand *, operand *);
46 operand *geniCodeAssign (operand *, operand *, int);
47 operand *geniCodeArray (operand *, operand *,int);
48 operand *geniCodeArray2Ptr (operand *);
49 operand *geniCodeRValue (operand *, bool);
50 operand *geniCodeDerefPtr (operand *,int);
51 int isLvaluereq(int lvl);
53 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
54 /* forward definition of ic print functions */
55 PRINTFUNC (picGetValueAtAddr);
56 PRINTFUNC (picSetValueAtAddr);
57 PRINTFUNC (picAddrOf);
58 PRINTFUNC (picGeneric);
59 PRINTFUNC (picGenericOne);
61 PRINTFUNC (picAssign);
65 PRINTFUNC (picJumpTable);
66 PRINTFUNC (picInline);
67 PRINTFUNC (picReceive);
69 iCodeTable codeTable[] =
71 {'!', "not", picGenericOne, NULL},
72 {'~', "~", picGenericOne, NULL},
73 {RRC, "rrc", picGenericOne, NULL},
74 {RLC, "rlc", picGenericOne, NULL},
75 {GETHBIT, "ghbit", picGenericOne, NULL},
76 {UNARYMINUS, "-", picGenericOne, NULL},
77 {IPUSH, "push", picGenericOne, NULL},
78 {IPOP, "pop", picGenericOne, NULL},
79 {CALL, "call", picGenericOne, NULL},
80 {PCALL, "pcall", picGenericOne, NULL},
81 {FUNCTION, "proc", picGenericOne, NULL},
82 {ENDFUNCTION, "eproc", picGenericOne, NULL},
83 {RETURN, "ret", picGenericOne, NULL},
84 {'+', "+", picGeneric, NULL},
85 {'-', "-", picGeneric, NULL},
86 {'*', "*", picGeneric, NULL},
87 {'/', "/", picGeneric, NULL},
88 {'%', "%", picGeneric, NULL},
89 {'>', ">", picGeneric, NULL},
90 {'<', "<", picGeneric, NULL},
91 {LE_OP, "<=", picGeneric, NULL},
92 {GE_OP, ">=", picGeneric, NULL},
93 {EQ_OP, "==", picGeneric, NULL},
94 {NE_OP, "!=", picGeneric, NULL},
95 {AND_OP, "&&", picGeneric, NULL},
96 {OR_OP, "||", picGeneric, NULL},
97 {'^', "^", picGeneric, NULL},
98 {'|', "|", picGeneric, NULL},
99 {BITWISEAND, "&", picGeneric, NULL},
100 {LEFT_OP, "<<", picGeneric, NULL},
101 {RIGHT_OP, ">>", picGeneric, NULL},
102 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
103 {ADDRESS_OF, "&", picAddrOf, NULL},
104 {CAST, "<>", picCast, NULL},
105 {'=', ":=", picAssign, NULL},
106 {LABEL, "", picLabel, NULL},
107 {GOTO, "", picGoto, NULL},
108 {JUMPTABLE, "jtab", picJumpTable, NULL},
109 {IFX, "if", picIfx, NULL},
110 {INLINEASM, "", picInline, NULL},
111 {RECEIVE, "recv", picReceive, NULL},
112 {SEND, "send", picGenericOne, NULL}
116 /*-----------------------------------------------------------------*/
117 /* operandName - returns the name of the operand */
118 /*-----------------------------------------------------------------*/
120 printOperand (operand * op, FILE * file)
137 opetype = getSpec (operandType (op));
138 if (SPEC_NOUN (opetype) == V_FLOAT)
139 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
141 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
142 printTypeChain (operandType (op), file);
149 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
150 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
152 OP_LIVEFROM (op), OP_LIVETO (op),
153 OP_SYMBOL (op)->stack,
154 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
158 printTypeChain (operandType (op), file);
159 if (SPIL_LOC (op) && IS_ITEMP (op))
160 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
165 /* if assigned to registers */
166 if (OP_SYMBOL (op)->nRegs)
168 if (OP_SYMBOL (op)->isspilt)
170 if (!OP_SYMBOL (op)->remat)
171 if (OP_SYMBOL (op)->usl.spillLoc)
172 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
173 OP_SYMBOL (op)->usl.spillLoc->rname :
174 OP_SYMBOL (op)->usl.spillLoc->name));
176 fprintf (file, "[err]");
178 fprintf (file, "[remat]");
184 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
185 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
190 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
191 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
192 /* if assigned to registers */
193 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
197 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
198 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
199 OP_SYMBOL (op)->regs[i]->name :
208 printTypeChain (op->operand.typeOperand, file);
214 fprintf (file, "\n");
219 /*-----------------------------------------------------------------*/
220 /* print functions */
221 /*-----------------------------------------------------------------*/
222 PRINTFUNC (picGetValueAtAddr)
225 printOperand (IC_RESULT (ic), of);
228 printOperand (IC_LEFT (ic), of);
234 PRINTFUNC (picSetValueAtAddr)
238 printOperand (IC_LEFT (ic), of);
239 fprintf (of, "] = ");
240 printOperand (IC_RIGHT (ic), of);
244 PRINTFUNC (picAddrOf)
247 printOperand (IC_RESULT (ic), of);
248 if (IS_ITEMP (IC_LEFT (ic)))
251 fprintf (of, " = &[");
252 printOperand (IC_LEFT (ic), of);
255 if (IS_ITEMP (IC_LEFT (ic)))
256 fprintf (of, " offsetAdd ");
259 printOperand (IC_RIGHT (ic), of);
261 if (IS_ITEMP (IC_LEFT (ic)))
267 PRINTFUNC (picJumpTable)
272 fprintf (of, "%s\t", s);
273 printOperand (IC_JTCOND (ic), of);
275 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
276 sym = setNextItem (IC_JTLABELS (ic)))
277 fprintf (of, "\t\t\t%s\n", sym->name);
280 PRINTFUNC (picGeneric)
283 printOperand (IC_RESULT (ic), of);
285 printOperand (IC_LEFT (ic), of);
286 fprintf (of, " %s ", s);
287 printOperand (IC_RIGHT (ic), of);
291 PRINTFUNC (picGenericOne)
296 printOperand (IC_RESULT (ic), of);
302 fprintf (of, "%s ", s);
303 printOperand (IC_LEFT (ic), of);
306 if (!IC_RESULT (ic) && !IC_LEFT (ic))
315 printOperand (IC_RESULT (ic), of);
317 printOperand (IC_LEFT (ic), of);
318 printOperand (IC_RIGHT (ic), of);
323 PRINTFUNC (picAssign)
327 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
330 printOperand (IC_RESULT (ic), of);
332 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
335 fprintf (of, " %s ", s);
336 printOperand (IC_RIGHT (ic), of);
343 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
349 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
356 printOperand (IC_COND (ic), of);
359 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
362 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
364 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
368 PRINTFUNC (picInline)
370 fprintf (of, "%s", IC_INLINE (ic));
373 PRINTFUNC (picReceive)
375 printOperand (IC_RESULT (ic), of);
376 fprintf (of, " = %s ", s);
377 printOperand (IC_LEFT (ic), of);
381 /*-----------------------------------------------------------------*/
382 /* piCode - prints one iCode */
383 /*-----------------------------------------------------------------*/
385 piCode (void *item, FILE * of)
393 icTab = getTableEntry (ic->op);
394 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
395 ic->filename, ic->lineno,
396 ic->seq, ic->key, ic->depth, ic->supportRtn);
397 icTab->iCodePrint (of, ic, icTab->printName);
403 printiCChain(ic,stdout);
405 /*-----------------------------------------------------------------*/
406 /* printiCChain - prints intermediate code for humans */
407 /*-----------------------------------------------------------------*/
409 printiCChain (iCode * icChain, FILE * of)
416 for (loop = icChain; loop; loop = loop->next)
418 if ((icTab = getTableEntry (loop->op)))
420 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
421 loop->filename, loop->lineno,
422 loop->seq, loop->key, loop->depth, loop->supportRtn);
424 icTab->iCodePrint (of, loop, icTab->printName);
430 /*-----------------------------------------------------------------*/
431 /* newOperand - allocate, init & return a new iCode */
432 /*-----------------------------------------------------------------*/
438 op = Safe_calloc (1, sizeof (operand));
444 /*-----------------------------------------------------------------*/
445 /* newiCode - create and return a new iCode entry initialised */
446 /*-----------------------------------------------------------------*/
448 newiCode (int op, operand * left, operand * right)
452 ic = Safe_calloc (1, sizeof (iCode));
455 ic->filename = filename;
457 ic->level = scopeLevel;
459 ic->key = iCodeKey++;
461 IC_RIGHT (ic) = right;
466 /*-----------------------------------------------------------------*/
467 /* newiCode for conditional statements */
468 /*-----------------------------------------------------------------*/
470 newiCodeCondition (operand * condition,
476 ic = newiCode (IFX, NULL, NULL);
477 IC_COND (ic) = condition;
478 IC_TRUE (ic) = trueLabel;
479 IC_FALSE (ic) = falseLabel;
483 /*-----------------------------------------------------------------*/
484 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
485 /*-----------------------------------------------------------------*/
487 newiCodeLabelGoto (int op, symbol * label)
491 ic = newiCode (op, NULL, NULL);
493 ic->argLabel.label = label;
495 IC_RIGHT (ic) = NULL;
496 IC_RESULT (ic) = NULL;
500 /*-----------------------------------------------------------------*/
501 /* newiTemp - allocate & return a newItemp Variable */
502 /*-----------------------------------------------------------------*/
509 sprintf (buffer, "%s", s);
511 sprintf (buffer, "iTemp%d", iTempNum++);
512 itmp = newSymbol (buffer, 1);
513 strcpy (itmp->rname, itmp->name);
519 /*-----------------------------------------------------------------*/
520 /* newiTempLabel - creates a temp variable label */
521 /*-----------------------------------------------------------------*/
523 newiTempLabel (char *s)
527 /* check if this alredy exists */
528 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
532 itmplbl = newSymbol (s, 1);
535 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
536 itmplbl = newSymbol (buffer, 1);
541 itmplbl->key = labelKey++;
542 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
546 /*-----------------------------------------------------------------*/
547 /* newiTempPreheaderLabel - creates a new preheader label */
548 /*-----------------------------------------------------------------*/
550 newiTempPreheaderLabel ()
554 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
555 itmplbl = newSymbol (buffer, 1);
559 itmplbl->key = labelKey++;
560 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
565 /*-----------------------------------------------------------------*/
566 /* initiCode - initialises some iCode related stuff */
567 /*-----------------------------------------------------------------*/
574 /*-----------------------------------------------------------------*/
575 /* copyiCode - make a copy of the iCode given */
576 /*-----------------------------------------------------------------*/
578 copyiCode (iCode * ic)
580 iCode *nic = newiCode (ic->op, NULL, NULL);
582 nic->lineno = ic->lineno;
583 nic->filename = ic->filename;
584 nic->block = ic->block;
585 nic->level = ic->level;
586 nic->parmBytes = ic->parmBytes;
588 /* deal with the special cases first */
592 IC_COND (nic) = operandFromOperand (IC_COND (ic));
593 IC_TRUE (nic) = IC_TRUE (ic);
594 IC_FALSE (nic) = IC_FALSE (ic);
598 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
599 IC_JTLABELS (nic) = IC_JTLABELS (ic);
604 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
605 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
606 IC_ARGS (nic) = IC_ARGS (ic);
610 IC_INLINE (nic) = IC_INLINE (ic);
614 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
615 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
616 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
622 /*-----------------------------------------------------------------*/
623 /* getTableEntry - gets the table entry for the given operator */
624 /*-----------------------------------------------------------------*/
626 getTableEntry (int oper)
630 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
631 if (oper == codeTable[i].icode)
632 return &codeTable[i];
637 /*-----------------------------------------------------------------*/
638 /* newiTempOperand - new intermediate temp operand */
639 /*-----------------------------------------------------------------*/
641 newiTempOperand (sym_link * type, char throwType)
644 operand *op = newOperand ();
648 itmp = newiTemp (NULL);
650 etype = getSpec (type);
652 if (IS_LITERAL (etype))
655 /* copy the type information */
657 itmp->etype = getSpec (itmp->type = (throwType ? type :
658 copyLinkChain (type)));
659 if (IS_LITERAL (itmp->etype))
661 SPEC_SCLS (itmp->etype) = S_REGISTER;
662 SPEC_OCLS (itmp->etype) = reg;
665 op->operand.symOperand = itmp;
666 op->key = itmp->key = ++operandKey;
670 /*-----------------------------------------------------------------*/
671 /* operandType - returns the type chain for an operand */
672 /*-----------------------------------------------------------------*/
674 operandType (operand * op)
676 /* depending on type of operand */
681 return op->operand.valOperand->type;
684 return op->operand.symOperand->type;
687 return op->operand.typeOperand;
689 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
690 " operand type not known ");
691 assert (0); /* should never come here */
692 /* Just to keep the compiler happy */
693 return (sym_link *) 0;
697 /*-----------------------------------------------------------------*/
698 /* isParamterToCall - will return 1 if op is a parameter to args */
699 /*-----------------------------------------------------------------*/
701 isParameterToCall (value * args, operand * op)
708 isSymbolEqual (op->operand.symOperand, tval->sym))
715 /*-----------------------------------------------------------------*/
716 /* isOperandGlobal - return 1 if operand is a global variable */
717 /*-----------------------------------------------------------------*/
719 isOperandGlobal (operand * op)
727 if (op->type == SYMBOL &&
728 (op->operand.symOperand->level == 0 ||
729 IS_STATIC (op->operand.symOperand->etype) ||
730 IS_EXTERN (op->operand.symOperand->etype))
737 /*-----------------------------------------------------------------*/
738 /* isOperandVolatile - return 1 if the operand is volatile */
739 /*-----------------------------------------------------------------*/
741 isOperandVolatile (operand * op, bool chkTemp)
746 if (IS_ITEMP (op) && !chkTemp)
749 opetype = getSpec (optype = operandType (op));
751 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
754 if (IS_VOLATILE (opetype))
759 /*-----------------------------------------------------------------*/
760 /* isOperandLiteral - returns 1 if an operand contains a literal */
761 /*-----------------------------------------------------------------*/
763 isOperandLiteral (operand * op)
770 opetype = getSpec (operandType (op));
772 if (IS_LITERAL (opetype))
777 /*-----------------------------------------------------------------*/
778 /* isOperandInFarSpace - will return true if operand is in farSpace */
779 /*-----------------------------------------------------------------*/
781 isOperandInFarSpace (operand * op)
791 if (!IS_TRUE_SYMOP (op))
794 etype = SPIL_LOC (op)->etype;
800 etype = getSpec (operandType (op));
802 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
805 /*-----------------------------------------------------------------*/
806 /* isOperandOnStack - will return true if operand is on stack */
807 /*-----------------------------------------------------------------*/
809 isOperandOnStack (operand * op)
819 etype = getSpec (operandType (op));
821 return ((IN_STACK (etype)) ? TRUE : FALSE);
824 /*-----------------------------------------------------------------*/
825 /* operandLitValue - literal value of an operand */
826 /*-----------------------------------------------------------------*/
828 operandLitValue (operand * op)
830 assert (isOperandLiteral (op));
832 return floatFromVal (op->operand.valOperand);
835 /*-----------------------------------------------------------------*/
836 /* operandOperation - perforoms operations on operands */
837 /*-----------------------------------------------------------------*/
839 operandOperation (operand * left, operand * right,
840 int op, sym_link * type)
842 sym_link *let , *ret=NULL;
843 operand *retval = (operand *) 0;
845 assert (isOperandLiteral (left));
846 let = getSpec(operandType(left));
848 assert (isOperandLiteral (right));
849 ret = getSpec(operandType(left));
855 retval = operandFromValue (valCastLiteral (type,
856 operandLitValue (left) +
857 operandLitValue (right)));
860 retval = operandFromValue (valCastLiteral (type,
861 operandLitValue (left) -
862 operandLitValue (right)));
865 retval = operandFromValue (valCastLiteral (type,
866 operandLitValue (left) *
867 operandLitValue (right)));
870 if ((unsigned long) operandLitValue (right) == 0)
872 werror (E_DIVIDE_BY_ZERO);
877 retval = operandFromValue (valCastLiteral (type,
878 operandLitValue (left) /
879 operandLitValue (right)));
882 if ((unsigned long) operandLitValue (right) == 0) {
883 werror (E_DIVIDE_BY_ZERO);
887 retval = operandFromLit ((SPEC_USIGN(let) ?
888 (unsigned long) operandLitValue (left) :
889 (long) operandLitValue (left)) %
891 (unsigned long) operandLitValue (right) :
892 (long) operandLitValue (right)));
896 retval = operandFromLit (((SPEC_USIGN(let) ?
897 (unsigned long) operandLitValue (left) :
898 (long) operandLitValue (left)) <<
900 (unsigned long) operandLitValue (right) :
901 (long) operandLitValue (right))));
904 retval = operandFromLit (((SPEC_USIGN(let) ?
905 (unsigned long) operandLitValue (left) :
906 (long) operandLitValue (left)) >>
908 (unsigned long) operandLitValue (right) :
909 (long) operandLitValue (right))));
912 retval = operandFromLit (operandLitValue (left) ==
913 operandLitValue (right));
916 retval = operandFromLit (operandLitValue (left) <
917 operandLitValue (right));
920 retval = operandFromLit (operandLitValue (left) <=
921 operandLitValue (right));
924 retval = operandFromLit (operandLitValue (left) !=
925 operandLitValue (right));
928 retval = operandFromLit (operandLitValue (left) >
929 operandLitValue (right));
932 retval = operandFromLit (operandLitValue (left) >=
933 operandLitValue (right));
936 retval = operandFromLit ((unsigned long) operandLitValue (left) &
937 (unsigned long) operandLitValue (right));
940 retval = operandFromLit ((unsigned long) operandLitValue (left) |
941 (unsigned long) operandLitValue (right));
944 retval = operandFromLit ((unsigned long) operandLitValue (left) ^
945 (unsigned long) operandLitValue (right));
948 retval = operandFromLit (operandLitValue (left) &&
949 operandLitValue (right));
952 retval = operandFromLit (operandLitValue (left) ||
953 operandLitValue (right));
957 long i = (long) operandLitValue (left);
959 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
965 long i = (long) operandLitValue (left);
967 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
973 retval = operandFromLit (-1 * operandLitValue (left));
977 retval = operandFromLit (~((long) operandLitValue (left)));
981 retval = operandFromLit (!operandLitValue (left));
985 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
986 " operandOperation invalid operator ");
994 /*-----------------------------------------------------------------*/
995 /* isOperandEqual - compares two operand & return 1 if they r = */
996 /*-----------------------------------------------------------------*/
998 isOperandEqual (operand * left, operand * right)
1000 /* if the pointers are equal then they are equal */
1004 /* if either of them null then false */
1005 if (!left || !right)
1008 if (left->type != right->type)
1011 if (IS_SYMOP (left) && IS_SYMOP (right))
1012 return left->key == right->key;
1014 /* if types are the same */
1018 return isSymbolEqual (left->operand.symOperand,
1019 right->operand.symOperand);
1021 return (floatFromVal (left->operand.valOperand) ==
1022 floatFromVal (right->operand.valOperand));
1024 if (compareType (left->operand.typeOperand,
1025 right->operand.typeOperand) == 1)
1032 /*-----------------------------------------------------------------*/
1033 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1034 /*-----------------------------------------------------------------*/
1036 isiCodeEqual (iCode * left, iCode * right)
1038 /* if the same pointer */
1042 /* if either of them null */
1043 if (!left || !right)
1046 /* if operand are the same */
1047 if (left->op == right->op)
1050 /* compare all the elements depending on type */
1051 if (left->op != IFX)
1053 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1055 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1061 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1063 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1065 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1073 /*-----------------------------------------------------------------*/
1074 /* newiTempFromOp - create a temp Operand with same attributes */
1075 /*-----------------------------------------------------------------*/
1077 newiTempFromOp (operand * op)
1087 nop = newiTempOperand (operandType (op), TRUE);
1088 nop->isaddr = op->isaddr;
1089 nop->isvolatile = op->isvolatile;
1090 nop->isGlobal = op->isGlobal;
1091 nop->isLiteral = op->isLiteral;
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->usesDefs = op->usesDefs;
1115 nop->isParm = op->isParm;
1120 nop->operand.symOperand = op->operand.symOperand;
1123 nop->operand.valOperand = op->operand.valOperand;
1126 nop->operand.typeOperand = op->operand.typeOperand;
1133 /*-----------------------------------------------------------------*/
1134 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1135 /*-----------------------------------------------------------------*/
1137 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1139 operand *nop = operandFromOperand (op);
1141 if (nop->type == SYMBOL)
1143 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1144 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1150 /*-----------------------------------------------------------------*/
1151 /* operandFromSymbol - creates an operand from a symbol */
1152 /*-----------------------------------------------------------------*/
1154 operandFromSymbol (symbol * sym)
1159 /* if the symbol's type is a literal */
1160 /* then it is an enumerator type */
1161 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1162 return operandFromValue (valFromType (sym->etype));
1165 sym->key = ++operandKey;
1167 /* if this an implicit variable, means struct/union */
1168 /* member so just return it */
1169 if (sym->implicit || IS_FUNC (sym->type))
1173 op->operand.symOperand = sym;
1175 op->isvolatile = isOperandVolatile (op, TRUE);
1176 op->isGlobal = isOperandGlobal (op);
1180 /* under the following conditions create a
1181 register equivalent for a local symbol */
1182 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1183 (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) &&
1184 options.stackAuto == 0)
1187 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1188 !IS_FUNC (sym->type) && /* not a function */
1189 !sym->_isparm && /* not a parameter */
1190 sym->level && /* is a local variable */
1191 !sym->addrtaken && /* whose address has not been taken */
1192 !sym->reqv && /* does not already have a register euivalence */
1193 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1194 !IS_STATIC (sym->etype) && /* and not declared static */
1195 !sym->islbl && /* not a label */
1196 ok && /* farspace check */
1197 !IS_BITVAR (sym->etype) /* not a bit variable */
1201 /* we will use it after all optimizations
1202 and before liveRange calculation */
1203 sym->reqv = newiTempOperand (sym->type, 0);
1204 sym->reqv->key = sym->key;
1205 OP_SYMBOL (sym->reqv)->key = sym->key;
1206 OP_SYMBOL (sym->reqv)->isreqv = 1;
1207 OP_SYMBOL (sym->reqv)->islocal = 1;
1208 SPIL_LOC (sym->reqv) = sym;
1211 if (!IS_AGGREGATE (sym->type))
1215 op->operand.symOperand = sym;
1218 op->isvolatile = isOperandVolatile (op, TRUE);
1219 op->isGlobal = isOperandGlobal (op);
1220 op->isPtr = IS_PTR (operandType (op));
1221 op->isParm = sym->_isparm;
1226 /* itemp = &[_symbol] */
1228 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1229 IC_LEFT (ic)->type = SYMBOL;
1230 IC_LEFT (ic)->operand.symOperand = sym;
1231 IC_LEFT (ic)->key = sym->key;
1232 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1233 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1234 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1237 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1238 if (IS_ARRAY (sym->type))
1240 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1241 IC_RESULT (ic)->isaddr = 0;
1244 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1246 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1250 return IC_RESULT (ic);
1253 /*-----------------------------------------------------------------*/
1254 /* operandFromValue - creates an operand from value */
1255 /*-----------------------------------------------------------------*/
1257 operandFromValue (value * val)
1261 /* if this is a symbol then do the symbol thing */
1263 return operandFromSymbol (val->sym);
1265 /* this is not a symbol */
1268 op->operand.valOperand = val;
1269 op->isLiteral = isOperandLiteral (op);
1273 /*-----------------------------------------------------------------*/
1274 /* operandFromLink - operand from typeChain */
1275 /*-----------------------------------------------------------------*/
1277 operandFromLink (sym_link * type)
1281 /* operand from sym_link */
1287 op->operand.typeOperand = copyLinkChain (type);
1291 /*-----------------------------------------------------------------*/
1292 /* operandFromLit - makes an operand from a literal value */
1293 /*-----------------------------------------------------------------*/
1295 operandFromLit (double i)
1297 return operandFromValue (valueFromLit (i));
1300 /*-----------------------------------------------------------------*/
1301 /* operandFromAst - creates an operand from an ast */
1302 /*-----------------------------------------------------------------*/
1304 operandFromAst (ast * tree,int lvl)
1310 /* depending on type do */
1314 return ast2iCode (tree,lvl+1);
1318 return operandFromValue (tree->opval.val);
1322 return operandFromLink (tree->opval.lnk);
1326 /* Just to keep the comiler happy */
1327 return (operand *) 0;
1330 /*-----------------------------------------------------------------*/
1331 /* setOperandType - sets the operand's type to the given type */
1332 /*-----------------------------------------------------------------*/
1334 setOperandType (operand * op, sym_link * type)
1336 /* depending on the type of operand */
1341 op->operand.valOperand->etype =
1342 getSpec (op->operand.valOperand->type =
1343 copyLinkChain (type));
1347 if (op->operand.symOperand->isitmp)
1348 op->operand.symOperand->etype =
1349 getSpec (op->operand.symOperand->type =
1350 copyLinkChain (type));
1352 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1353 "attempt to modify type of source");
1357 op->operand.typeOperand = copyLinkChain (type);
1362 /*-----------------------------------------------------------------*/
1363 /* Get size in byte of ptr need to access an array */
1364 /*-----------------------------------------------------------------*/
1366 getArraySizePtr (operand * op)
1368 sym_link *ltype = operandType(op);
1372 int size = getSize(ltype);
1373 return(IS_GENPTR(ltype)?(size-1):size);
1378 sym_link *letype = getSpec(ltype);
1379 switch (PTR_TYPE (SPEC_OCLS (letype)))
1391 return (GPTRSIZE-1);
1400 /*-----------------------------------------------------------------*/
1401 /* perform "usual unary conversions" */
1402 /*-----------------------------------------------------------------*/
1404 usualUnaryConversions (operand * op)
1406 if (IS_INTEGRAL (operandType (op)))
1408 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1411 return geniCodeCast (INTTYPE, op, TRUE);
1417 /*-----------------------------------------------------------------*/
1418 /* perform "usual binary conversions" */
1419 /*-----------------------------------------------------------------*/
1421 usualBinaryConversions (operand ** op1, operand ** op2)
1424 sym_link *rtype = operandType (*op2);
1425 sym_link *ltype = operandType (*op1);
1427 ctype = computeType (ltype, rtype);
1428 *op1 = geniCodeCast (ctype, *op1, TRUE);
1429 *op2 = geniCodeCast (ctype, *op2, TRUE);
1434 /*-----------------------------------------------------------------*/
1435 /* geniCodeValueAtAddress - generate intermeditate code for value */
1437 /*-----------------------------------------------------------------*/
1439 geniCodeRValue (operand * op, bool force)
1442 sym_link *type = operandType (op);
1443 sym_link *etype = getSpec (type);
1445 /* if this is an array & already */
1446 /* an address then return this */
1447 if (IS_AGGREGATE (type) ||
1448 (IS_PTR (type) && !force && !op->isaddr))
1449 return operandFromOperand (op);
1451 /* if this is not an address then must be */
1452 /* rvalue already so return this one */
1456 /* if this is not a temp symbol then */
1457 if (!IS_ITEMP (op) &&
1459 !IN_FARSPACE (SPEC_OCLS (etype)))
1461 op = operandFromOperand (op);
1466 if (IS_SPEC (type) &&
1467 IS_TRUE_SYMOP (op) &&
1468 (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
1470 op = operandFromOperand (op);
1475 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1476 if (IS_PTR (type) && op->isaddr && force)
1479 type = copyLinkChain (type);
1481 IC_RESULT (ic) = newiTempOperand (type, 1);
1482 IC_RESULT (ic)->isaddr = 0;
1484 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1486 /* if the right is a symbol */
1487 if (op->type == SYMBOL)
1488 IC_RESULT (ic)->operand.symOperand->args =
1489 op->operand.symOperand->args;
1492 return IC_RESULT (ic);
1495 /*-----------------------------------------------------------------*/
1496 /* geniCodeCast - changes the value from one type to another */
1497 /*-----------------------------------------------------------------*/
1499 geniCodeCast (sym_link * type, operand * op, bool implicit)
1503 sym_link *opetype = getSpec (optype = operandType (op));
1506 /* one of them has size zero then error */
1507 if (IS_VOID (optype))
1509 werror (E_CAST_ZERO);
1513 /* if the operand is already the desired type then do nothing */
1514 if (compareType (type, optype) == 1)
1517 /* if this is a literal then just change the type & return */
1518 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1519 return operandFromValue (valCastLiteral (type,
1520 operandLitValue (op)));
1522 /* if casting to some pointer type &&
1523 the destination is not a generic pointer
1524 then give a warning : (only for implicit casts) */
1525 if (IS_PTR (optype) && implicit &&
1526 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1529 werror (E_INCOMPAT_CAST);
1530 fprintf (stderr, "from type '");
1531 printTypeChain (optype, stderr);
1532 fprintf (stderr, "' to type '");
1533 printTypeChain (type, stderr);
1534 fprintf (stderr, "'\n");
1537 /* if they are the same size create an assignment */
1538 if (getSize (type) == getSize (optype) &&
1539 !IS_BITFIELD (type) &&
1541 !IS_FLOAT (optype) &&
1542 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1543 (!IS_SPEC (type) && !IS_SPEC (optype))))
1546 ic = newiCode ('=', NULL, op);
1547 IC_RESULT (ic) = newiTempOperand (type, 0);
1548 SPIL_LOC (IC_RESULT (ic)) =
1549 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1550 IC_RESULT (ic)->isaddr = 0;
1554 ic = newiCode (CAST, operandFromLink (type),
1555 geniCodeRValue (op, FALSE));
1557 IC_RESULT (ic) = newiTempOperand (type, 0);
1560 /* preserve the storage class & output class */
1561 /* of the original variable */
1562 restype = getSpec (operandType (IC_RESULT (ic)));
1563 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1564 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1567 return IC_RESULT (ic);
1570 /*-----------------------------------------------------------------*/
1571 /* geniCodeLabel - will create a Label */
1572 /*-----------------------------------------------------------------*/
1574 geniCodeLabel (symbol * label)
1578 ic = newiCodeLabelGoto (LABEL, label);
1582 /*-----------------------------------------------------------------*/
1583 /* geniCodeGoto - will create a Goto */
1584 /*-----------------------------------------------------------------*/
1586 geniCodeGoto (symbol * label)
1590 ic = newiCodeLabelGoto (GOTO, label);
1594 /*-----------------------------------------------------------------*/
1595 /* geniCodeMultiply - gen intermediate code for multiplication */
1596 /*-----------------------------------------------------------------*/
1598 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1605 /* if they are both literal then we know the result */
1606 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1607 return operandFromValue (valMult (left->operand.valOperand,
1608 right->operand.valOperand));
1610 if (IS_LITERAL(retype)) {
1611 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1614 resType = usualBinaryConversions (&left, &right);
1616 rtype = operandType (right);
1617 retype = getSpec (rtype);
1618 ltype = operandType (left);
1619 letype = getSpec (ltype);
1623 SPEC_NOUN(getSpec(resType))=V_INT;
1626 /* if the right is a literal & power of 2 */
1627 /* then make it a left shift */
1628 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1629 efficient in most cases than 2 bytes result = 2 bytes << literal
1630 if port has 1 byte muldiv */
1631 if (p2 && !IS_FLOAT (letype) &&
1632 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1633 (port->support.muldiv == 1)))
1635 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1637 /* LEFT_OP need same size for left and result, */
1638 left = geniCodeCast (resType, left, TRUE);
1639 ltype = operandType (left);
1641 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1645 ic = newiCode ('*', left, right); /* normal multiplication */
1646 /* if the size left or right > 1 then support routine */
1647 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1651 IC_RESULT (ic) = newiTempOperand (resType, 1);
1654 return IC_RESULT (ic);
1657 /*-----------------------------------------------------------------*/
1658 /* geniCodeDivision - gen intermediate code for division */
1659 /*-----------------------------------------------------------------*/
1661 geniCodeDivision (operand * left, operand * right)
1666 sym_link *rtype = operandType (right);
1667 sym_link *retype = getSpec (rtype);
1668 sym_link *ltype = operandType (left);
1669 sym_link *letype = getSpec (ltype);
1671 resType = usualBinaryConversions (&left, &right);
1673 /* if the right is a literal & power of 2 */
1674 /* then make it a right shift */
1675 if (IS_LITERAL (retype) &&
1676 !IS_FLOAT (letype) &&
1677 (p2 = powof2 ((unsigned long)
1678 floatFromVal (right->operand.valOperand)))) {
1679 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1683 ic = newiCode ('/', left, right); /* normal division */
1684 /* if the size left or right > 1 then support routine */
1685 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1688 IC_RESULT (ic) = newiTempOperand (resType, 0);
1691 return IC_RESULT (ic);
1693 /*-----------------------------------------------------------------*/
1694 /* geniCodeModulus - gen intermediate code for modulus */
1695 /*-----------------------------------------------------------------*/
1697 geniCodeModulus (operand * left, operand * right)
1703 /* if they are both literal then we know the result */
1704 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1705 return operandFromValue (valMod (left->operand.valOperand,
1706 right->operand.valOperand));
1708 resType = usualBinaryConversions (&left, &right);
1710 /* now they are the same size */
1711 ic = newiCode ('%', left, right);
1713 /* if the size left or right > 1 then support routine */
1714 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1716 IC_RESULT (ic) = newiTempOperand (resType, 0);
1719 return IC_RESULT (ic);
1722 /*-----------------------------------------------------------------*/
1723 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1724 /*-----------------------------------------------------------------*/
1726 geniCodePtrPtrSubtract (operand * left, operand * right)
1732 /* if they are both literals then */
1733 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1735 result = operandFromValue (valMinus (left->operand.valOperand,
1736 right->operand.valOperand));
1740 ic = newiCode ('-', left, right);
1742 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1746 return geniCodeDivision (result,
1747 operandFromLit (getSize (ltype->next)));
1750 /*-----------------------------------------------------------------*/
1751 /* geniCodeSubtract - generates code for subtraction */
1752 /*-----------------------------------------------------------------*/
1754 geniCodeSubtract (operand * left, operand * right)
1761 /* if they both pointers then */
1762 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1763 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1764 return geniCodePtrPtrSubtract (left, right);
1766 /* if they are both literal then we know the result */
1767 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1768 && left->isLiteral && right->isLiteral)
1769 return operandFromValue (valMinus (left->operand.valOperand,
1770 right->operand.valOperand));
1772 /* if left is an array or pointer */
1773 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1775 isarray = left->isaddr;
1776 right = geniCodeMultiply (right,
1777 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1778 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1781 { /* make them the same size */
1782 resType = usualBinaryConversions (&left, &right);
1785 ic = newiCode ('-', left, right);
1787 IC_RESULT (ic) = newiTempOperand (resType, 1);
1788 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1790 /* if left or right is a float */
1791 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1795 return IC_RESULT (ic);
1798 /*-----------------------------------------------------------------*/
1799 /* geniCodeAdd - generates iCode for addition */
1800 /*-----------------------------------------------------------------*/
1802 geniCodeAdd (operand * left, operand * right,int lvl)
1810 /* if left is an array then array access */
1811 if (IS_ARRAY (ltype))
1812 return geniCodeArray (left, right,lvl);
1814 /* if the right side is LITERAL zero */
1815 /* return the left side */
1816 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1819 /* if left is literal zero return right */
1820 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1823 /* if left is an array or pointer then size */
1826 isarray = left->isaddr;
1827 // there is no need to multiply with 1
1828 if (getSize(ltype->next)!=1) {
1829 size = operandFromLit (getSize (ltype->next));
1830 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1832 resType = copyLinkChain (ltype);
1835 { /* make them the same size */
1836 resType = usualBinaryConversions (&left, &right);
1839 /* if they are both literals then we know */
1840 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1841 && left->isLiteral && right->isLiteral)
1842 return operandFromValue (valPlus (valFromType (letype),
1843 valFromType (retype)));
1845 ic = newiCode ('+', left, right);
1847 IC_RESULT (ic) = newiTempOperand (resType, 1);
1848 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1850 /* if left or right is a float then support
1852 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1857 return IC_RESULT (ic);
1861 /*-----------------------------------------------------------------*/
1862 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1863 /*-----------------------------------------------------------------*/
1865 aggrToPtr (sym_link * type, bool force)
1871 if (IS_PTR (type) && !force)
1874 etype = getSpec (type);
1878 /* if the output class is generic */
1879 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1880 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1882 /* if the variable was declared a constant */
1883 /* then the pointer points to a constant */
1884 if (IS_CONSTANT (etype))
1885 DCL_PTR_CONST (ptype) = 1;
1887 /* the variable was volatile then pointer to volatile */
1888 if (IS_VOLATILE (etype))
1889 DCL_PTR_VOLATILE (ptype) = 1;
1893 /*-----------------------------------------------------------------*/
1894 /* geniCodeArray2Ptr - array to pointer */
1895 /*-----------------------------------------------------------------*/
1897 geniCodeArray2Ptr (operand * op)
1899 sym_link *optype = operandType (op);
1900 sym_link *opetype = getSpec (optype);
1902 /* set the pointer depending on the storage class */
1903 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1904 DCL_PTR_CONST (optype) = port->mem.code_ro;
1907 /* if the variable was declared a constant */
1908 /* then the pointer points to a constant */
1909 if (IS_CONSTANT (opetype))
1910 DCL_PTR_CONST (optype) = 1;
1912 /* the variable was volatile then pointer to volatile */
1913 if (IS_VOLATILE (opetype))
1914 DCL_PTR_VOLATILE (optype) = 1;
1920 /*-----------------------------------------------------------------*/
1921 /* geniCodeArray - array access */
1922 /*-----------------------------------------------------------------*/
1924 geniCodeArray (operand * left, operand * right,int lvl)
1927 sym_link *ltype = operandType (left);
1931 if (IS_PTR (ltype->next) && left->isaddr)
1933 left = geniCodeRValue (left, FALSE);
1935 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
1938 right = geniCodeMultiply (right,
1939 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1941 /* we can check for limits here */
1942 if (isOperandLiteral (right) &&
1945 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
1947 werror (E_ARRAY_BOUND);
1948 right = operandFromLit (0);
1951 ic = newiCode ('+', left, right);
1953 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
1954 !IS_AGGREGATE (ltype->next) &&
1955 !IS_PTR (ltype->next))
1956 ? ltype : ltype->next), 0);
1958 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
1960 return IC_RESULT (ic);
1963 /*-----------------------------------------------------------------*/
1964 /* geniCodeStruct - generates intermediate code for structres */
1965 /*-----------------------------------------------------------------*/
1967 geniCodeStruct (operand * left, operand * right, bool islval)
1970 sym_link *type = operandType (left);
1971 sym_link *etype = getSpec (type);
1973 symbol *element = getStructElement (SPEC_STRUCT (etype),
1974 right->operand.symOperand);
1976 /* add the offset */
1977 ic = newiCode ('+', left, operandFromLit (element->offset));
1979 IC_RESULT (ic) = newiTempOperand (element->type, 0);
1981 /* preserve the storage & output class of the struct */
1982 /* as well as the volatile attribute */
1983 retype = getSpec (operandType (IC_RESULT (ic)));
1984 SPEC_SCLS (retype) = SPEC_SCLS (etype);
1985 SPEC_OCLS (retype) = SPEC_OCLS (etype);
1986 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
1988 if (IS_PTR (element->type))
1989 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1991 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
1995 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
1998 /*-----------------------------------------------------------------*/
1999 /* geniCodePostInc - generate int code for Post increment */
2000 /*-----------------------------------------------------------------*/
2002 geniCodePostInc (operand * op)
2006 sym_link *optype = operandType (op);
2008 operand *rv = (IS_ITEMP (op) ?
2009 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2011 sym_link *rvtype = operandType (rv);
2014 /* if this is not an address we have trouble */
2017 werror (E_LVALUE_REQUIRED, "++");
2021 rOp = newiTempOperand (rvtype, 0);
2022 OP_SYMBOL(rOp)->noSpilLoc = 1;
2025 OP_SYMBOL(rv)->noSpilLoc = 1;
2027 geniCodeAssign (rOp, rv, 0);
2029 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2030 if (IS_FLOAT (rvtype))
2031 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2033 ic = newiCode ('+', rv, operandFromLit (size));
2035 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2038 geniCodeAssign (op, result, 0);
2044 /*-----------------------------------------------------------------*/
2045 /* geniCodePreInc - generate code for preIncrement */
2046 /*-----------------------------------------------------------------*/
2048 geniCodePreInc (operand * op)
2051 sym_link *optype = operandType (op);
2052 operand *rop = (IS_ITEMP (op) ?
2053 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2055 sym_link *roptype = operandType (rop);
2061 werror (E_LVALUE_REQUIRED, "++");
2066 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2067 if (IS_FLOAT (roptype))
2068 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2070 ic = newiCode ('+', rop, operandFromLit (size));
2071 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2075 return geniCodeAssign (op, result, 0);
2078 /*-----------------------------------------------------------------*/
2079 /* geniCodePostDec - generates code for Post decrement */
2080 /*-----------------------------------------------------------------*/
2082 geniCodePostDec (operand * op)
2086 sym_link *optype = operandType (op);
2088 operand *rv = (IS_ITEMP (op) ?
2089 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2091 sym_link *rvtype = operandType (rv);
2094 /* if this is not an address we have trouble */
2097 werror (E_LVALUE_REQUIRED, "++");
2101 rOp = newiTempOperand (rvtype, 0);
2102 OP_SYMBOL(rOp)->noSpilLoc = 1;
2105 OP_SYMBOL(rv)->noSpilLoc = 1;
2107 geniCodeAssign (rOp, rv, 0);
2109 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2110 if (IS_FLOAT (rvtype))
2111 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2113 ic = newiCode ('-', rv, operandFromLit (size));
2115 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2118 geniCodeAssign (op, result, 0);
2124 /*-----------------------------------------------------------------*/
2125 /* geniCodePreDec - generate code for pre decrement */
2126 /*-----------------------------------------------------------------*/
2128 geniCodePreDec (operand * op)
2131 sym_link *optype = operandType (op);
2132 operand *rop = (IS_ITEMP (op) ?
2133 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2135 sym_link *roptype = operandType (rop);
2141 werror (E_LVALUE_REQUIRED, "++");
2146 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2147 if (IS_FLOAT (roptype))
2148 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2150 ic = newiCode ('-', rop, operandFromLit (size));
2151 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2155 return geniCodeAssign (op, result, 0);
2159 /*-----------------------------------------------------------------*/
2160 /* geniCodeBitwise - gen int code for bitWise operators */
2161 /*-----------------------------------------------------------------*/
2163 geniCodeBitwise (operand * left, operand * right,
2164 int oper, sym_link * resType)
2168 left = geniCodeCast (resType, left, TRUE);
2169 right = geniCodeCast (resType, right, TRUE);
2171 ic = newiCode (oper, left, right);
2172 IC_RESULT (ic) = newiTempOperand (resType, 0);
2175 return IC_RESULT (ic);
2178 /*-----------------------------------------------------------------*/
2179 /* geniCodeAddressOf - gens icode for '&' address of operator */
2180 /*-----------------------------------------------------------------*/
2182 geniCodeAddressOf (operand * op)
2186 sym_link *optype = operandType (op);
2187 sym_link *opetype = getSpec (optype);
2189 /* lvalue check already done in decorateType */
2190 /* this must be a lvalue */
2191 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2192 /* werror (E_LVALUE_REQUIRED,"&"); */
2197 p->class = DECLARATOR;
2199 /* set the pointer depending on the storage class */
2200 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2201 DCL_PTR_CONST (p) = port->mem.code_ro;
2203 /* make sure we preserve the const & volatile */
2204 if (IS_CONSTANT (opetype))
2205 DCL_PTR_CONST (p) = 1;
2207 if (IS_VOLATILE (opetype))
2208 DCL_PTR_VOLATILE (p) = 1;
2210 p->next = copyLinkChain (optype);
2212 /* if already a temp */
2215 setOperandType (op, p);
2220 /* other wise make this of the type coming in */
2221 ic = newiCode (ADDRESS_OF, op, NULL);
2222 IC_RESULT (ic) = newiTempOperand (p, 1);
2223 IC_RESULT (ic)->isaddr = 0;
2225 return IC_RESULT (ic);
2227 /*-----------------------------------------------------------------*/
2228 /* setOClass - sets the output class depending on the pointer type */
2229 /*-----------------------------------------------------------------*/
2231 setOClass (sym_link * ptr, sym_link * spec)
2233 switch (DCL_TYPE (ptr))
2236 SPEC_OCLS (spec) = data;
2240 SPEC_OCLS (spec) = generic;
2244 SPEC_OCLS (spec) = xdata;
2248 SPEC_OCLS (spec) = code;
2252 SPEC_OCLS (spec) = idata;
2256 SPEC_OCLS (spec) = xstack;
2260 SPEC_OCLS (spec) = eeprom;
2269 /*-----------------------------------------------------------------*/
2270 /* geniCodeDerefPtr - dereference pointer with '*' */
2271 /*-----------------------------------------------------------------*/
2273 geniCodeDerefPtr (operand * op,int lvl)
2275 sym_link *rtype, *retype;
2276 sym_link *optype = operandType (op);
2278 /* if this is a pointer then generate the rvalue */
2279 if (IS_PTR (optype))
2281 if (IS_TRUE_SYMOP (op))
2284 op = geniCodeRValue (op, TRUE);
2287 op = geniCodeRValue (op, TRUE);
2290 /* now get rid of the pointer part */
2291 if (isLvaluereq(lvl) && IS_ITEMP (op))
2293 retype = getSpec (rtype = copyLinkChain (optype));
2297 retype = getSpec (rtype = copyLinkChain (optype->next));
2300 /* if this is a pointer then outputclass needs 2b updated */
2301 if (IS_PTR (optype))
2302 setOClass (optype, retype);
2304 op->isGptr = IS_GENPTR (optype);
2306 /* if the pointer was declared as a constant */
2307 /* then we cannot allow assignment to the derefed */
2308 if (IS_PTR_CONST (optype))
2309 SPEC_CONST (retype) = 1;
2311 op->isaddr = (IS_PTR (rtype) ||
2312 IS_STRUCT (rtype) ||
2317 if (!isLvaluereq(lvl))
2318 op = geniCodeRValue (op, TRUE);
2320 setOperandType (op, rtype);
2325 /*-----------------------------------------------------------------*/
2326 /* geniCodeUnaryMinus - does a unary minus of the operand */
2327 /*-----------------------------------------------------------------*/
2329 geniCodeUnaryMinus (operand * op)
2332 sym_link *optype = operandType (op);
2334 if (IS_LITERAL (optype))
2335 return operandFromLit (-floatFromVal (op->operand.valOperand));
2337 ic = newiCode (UNARYMINUS, op, NULL);
2338 IC_RESULT (ic) = newiTempOperand (optype, 0);
2340 return IC_RESULT (ic);
2343 /*-----------------------------------------------------------------*/
2344 /* geniCodeLeftShift - gen i code for left shift */
2345 /*-----------------------------------------------------------------*/
2347 geniCodeLeftShift (operand * left, operand * right)
2351 ic = newiCode (LEFT_OP, left, right);
2352 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2354 return IC_RESULT (ic);
2357 /*-----------------------------------------------------------------*/
2358 /* geniCodeRightShift - gen i code for right shift */
2359 /*-----------------------------------------------------------------*/
2361 geniCodeRightShift (operand * left, operand * right)
2365 ic = newiCode (RIGHT_OP, left, right);
2366 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2368 return IC_RESULT (ic);
2371 #if defined(__BORLANDC__) || defined(_MSC_VER)
2372 #define LONG_LONG __int64
2374 #define LONG_LONG long long
2377 /*-----------------------------------------------------------------*/
2378 /* geniCodeLogic- logic code */
2379 /*-----------------------------------------------------------------*/
2381 geniCodeLogic (operand * left, operand * right, int op)
2385 sym_link *rtype = operandType (right);
2386 sym_link *ltype = operandType (left);
2388 /* left is integral type and right is literal then
2389 check if the literal value is within bounds */
2390 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2392 int nbits = bitsForType (ltype);
2393 long v = (long) operandLitValue (right);
2395 if (v >= ((LONG_LONG) 1 << nbits) && v > 0)
2396 werror (W_CONST_RANGE, " compare operation ");
2399 ctype = usualBinaryConversions (&left, &right);
2401 ic = newiCode (op, left, right);
2402 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2404 /* if comparing float
2405 and not a '==' || '!=' || '&&' || '||' (these
2407 if (IS_FLOAT(ctype) &&
2415 return IC_RESULT (ic);
2418 /*-----------------------------------------------------------------*/
2419 /* geniCodeUnary - for a a generic unary operation */
2420 /*-----------------------------------------------------------------*/
2422 geniCodeUnary (operand * op, int oper)
2424 iCode *ic = newiCode (oper, op, NULL);
2426 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2428 return IC_RESULT (ic);
2431 /*-----------------------------------------------------------------*/
2432 /* geniCodeConditional - geniCode for '?' ':' operation */
2433 /*-----------------------------------------------------------------*/
2435 geniCodeConditional (ast * tree,int lvl)
2438 symbol *falseLabel = newiTempLabel (NULL);
2439 symbol *exitLabel = newiTempLabel (NULL);
2440 operand *cond = ast2iCode (tree->left,lvl+1);
2441 operand *true, *false, *result;
2443 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2447 true = ast2iCode (tree->right->left,lvl+1);
2449 /* move the value to a new Operand */
2450 result = newiTempOperand (operandType (true), 0);
2451 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2453 /* generate an unconditional goto */
2454 geniCodeGoto (exitLabel);
2456 /* now for the right side */
2457 geniCodeLabel (falseLabel);
2459 false = ast2iCode (tree->right->right,lvl+1);
2460 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2462 /* create the exit label */
2463 geniCodeLabel (exitLabel);
2468 /*-----------------------------------------------------------------*/
2469 /* geniCodeAssign - generate code for assignment */
2470 /*-----------------------------------------------------------------*/
2472 geniCodeAssign (operand * left, operand * right, int nosupdate)
2475 sym_link *ltype = operandType (left);
2476 sym_link *rtype = operandType (right);
2478 if (!left->isaddr && !IS_ITEMP (left))
2480 werror (E_LVALUE_REQUIRED, "assignment");
2484 /* left is integral type and right is literal then
2485 check if the literal value is within bounds */
2486 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2488 int nbits = bitsForType (ltype);
2489 long v = (long) operandLitValue (right);
2491 if (v >= ((LONG_LONG) 1 << nbits) && v > 0)
2492 werror (W_CONST_RANGE, " = operation");
2495 /* if the left & right type don't exactly match */
2496 /* if pointer set then make sure the check is
2497 done with the type & not the pointer */
2498 /* then cast rights type to left */
2500 /* first check the type for pointer assignement */
2501 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2502 compareType (ltype, rtype) < 0)
2504 if (compareType (ltype->next, rtype) < 0)
2505 right = geniCodeCast (ltype->next, right, TRUE);
2507 else if (compareType (ltype, rtype) < 0)
2508 right = geniCodeCast (ltype, right, TRUE);
2510 /* if left is a true symbol & ! volatile
2511 create an assignment to temporary for
2512 the right & then assign this temporary
2513 to the symbol this is SSA . isn't it simple
2514 and folks have published mountains of paper on it */
2515 if (IS_TRUE_SYMOP (left) &&
2516 !isOperandVolatile (left, FALSE) &&
2517 isOperandGlobal (left))
2521 if (IS_TRUE_SYMOP (right))
2522 sym = OP_SYMBOL (right);
2523 ic = newiCode ('=', NULL, right);
2524 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2525 SPIL_LOC (right) = sym;
2529 ic = newiCode ('=', NULL, right);
2530 IC_RESULT (ic) = left;
2533 /* if left isgptr flag is set then support
2534 routine will be required */
2538 ic->nosupdate = nosupdate;
2542 /*-----------------------------------------------------------------*/
2543 /* geniCodeSEParms - generate code for side effecting fcalls */
2544 /*-----------------------------------------------------------------*/
2546 geniCodeSEParms (ast * parms,int lvl)
2551 if (parms->type == EX_OP && parms->opval.op == PARAM)
2553 geniCodeSEParms (parms->left,lvl);
2554 geniCodeSEParms (parms->right,lvl);
2558 /* hack don't like this but too lazy to think of
2560 if (IS_ADDRESS_OF_OP (parms))
2561 parms->left->lvalue = 1;
2563 if (IS_CAST_OP (parms) &&
2564 IS_PTR (parms->ftype) &&
2565 IS_ADDRESS_OF_OP (parms->right))
2566 parms->right->left->lvalue = 1;
2568 parms->opval.oprnd =
2569 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2571 parms->type = EX_OPERAND;
2574 /*-----------------------------------------------------------------*/
2575 /* geniCodeParms - generates parameters */
2576 /*-----------------------------------------------------------------*/
2578 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2586 /* if this is a param node then do the left & right */
2587 if (parms->type == EX_OP && parms->opval.op == PARAM)
2589 geniCodeParms (parms->left, stack, fetype, func,lvl);
2590 geniCodeParms (parms->right, stack, fetype, func,lvl);
2594 /* get the parameter value */
2595 if (parms->type == EX_OPERAND)
2596 pval = parms->opval.oprnd;
2599 /* maybe this else should go away ?? */
2600 /* hack don't like this but too lazy to think of
2602 if (IS_ADDRESS_OF_OP (parms))
2603 parms->left->lvalue = 1;
2605 if (IS_CAST_OP (parms) &&
2606 IS_PTR (parms->ftype) &&
2607 IS_ADDRESS_OF_OP (parms->right))
2608 parms->right->left->lvalue = 1;
2610 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2613 /* if register parm then make it a send */
2614 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2615 IS_REGPARM (parms->etype)) && !func->hasVargs)
2617 ic = newiCode (SEND, pval, NULL);
2622 /* now decide whether to push or assign */
2623 if (!(options.stackAuto || IS_RENT (fetype)))
2627 operand *top = operandFromSymbol (parms->argSym);
2628 geniCodeAssign (top, pval, 1);
2632 sym_link *p = operandType (pval);
2634 ic = newiCode (IPUSH, pval, NULL);
2636 /* update the stack adjustment */
2637 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2644 /*-----------------------------------------------------------------*/
2645 /* geniCodeCall - generates temp code for calling */
2646 /*-----------------------------------------------------------------*/
2648 geniCodeCall (operand * left, ast * parms,int lvl)
2652 sym_link *type, *etype;
2655 /* take care of parameters with side-effecting
2656 function calls in them, this is required to take care
2657 of overlaying function parameters */
2658 geniCodeSEParms (parms,lvl);
2660 /* first the parameters */
2661 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2663 /* now call : if symbol then pcall */
2664 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2665 ic = newiCode (PCALL, left, NULL);
2667 ic = newiCode (CALL, left, NULL);
2669 IC_ARGS (ic) = left->operand.symOperand->args;
2670 type = copyLinkChain (operandType (left)->next);
2671 etype = getSpec (type);
2672 SPEC_EXTR (etype) = 0;
2673 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2677 /* stack adjustment after call */
2678 ic->parmBytes = stack;
2683 /*-----------------------------------------------------------------*/
2684 /* geniCodeReceive - generate intermediate code for "receive" */
2685 /*-----------------------------------------------------------------*/
2687 geniCodeReceive (value * args)
2689 /* for all arguments that are passed in registers */
2693 if (IS_REGPARM (args->etype))
2695 operand *opr = operandFromValue (args);
2697 symbol *sym = OP_SYMBOL (opr);
2700 /* we will use it after all optimizations
2701 and before liveRange calculation */
2702 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2705 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2706 options.stackAuto == 0 &&
2712 opl = newiTempOperand (args->type, 0);
2714 sym->reqv->key = sym->key;
2715 OP_SYMBOL (sym->reqv)->key = sym->key;
2716 OP_SYMBOL (sym->reqv)->isreqv = 1;
2717 OP_SYMBOL (sym->reqv)->islocal = 0;
2718 SPIL_LOC (sym->reqv) = sym;
2722 ic = newiCode (RECEIVE, NULL, NULL);
2723 currFunc->recvSize = getSize (sym->etype);
2724 IC_RESULT (ic) = opr;
2732 /*-----------------------------------------------------------------*/
2733 /* geniCodeFunctionBody - create the function body */
2734 /*-----------------------------------------------------------------*/
2736 geniCodeFunctionBody (ast * tree,int lvl)
2743 /* reset the auto generation */
2749 func = ast2iCode (tree->left,lvl+1);
2750 fetype = getSpec (operandType (func));
2752 savelineno = lineno;
2753 lineno = OP_SYMBOL (func)->lineDef;
2754 /* create an entry label */
2755 geniCodeLabel (entryLabel);
2756 lineno = savelineno;
2758 /* create a proc icode */
2759 ic = newiCode (FUNCTION, func, NULL);
2760 /* if the function has parmas then */
2761 /* save the parameters information */
2762 ic->argLabel.args = tree->values.args;
2763 ic->lineno = OP_SYMBOL (func)->lineDef;
2767 /* for all parameters that are passed
2768 on registers add a "receive" */
2769 geniCodeReceive (tree->values.args);
2771 /* generate code for the body */
2772 ast2iCode (tree->right,lvl+1);
2774 /* create a label for return */
2775 geniCodeLabel (returnLabel);
2777 /* now generate the end proc */
2778 ic = newiCode (ENDFUNCTION, func, NULL);
2783 /*-----------------------------------------------------------------*/
2784 /* geniCodeReturn - gen icode for 'return' statement */
2785 /*-----------------------------------------------------------------*/
2787 geniCodeReturn (operand * op)
2791 /* if the operand is present force an rvalue */
2793 op = geniCodeRValue (op, FALSE);
2795 ic = newiCode (RETURN, op, NULL);
2799 /*-----------------------------------------------------------------*/
2800 /* geniCodeIfx - generates code for extended if statement */
2801 /*-----------------------------------------------------------------*/
2803 geniCodeIfx (ast * tree,int lvl)
2806 operand *condition = ast2iCode (tree->left,lvl+1);
2809 /* if condition is null then exit */
2813 condition = geniCodeRValue (condition, FALSE);
2815 cetype = getSpec (operandType (condition));
2816 /* if the condition is a literal */
2817 if (IS_LITERAL (cetype))
2819 if (floatFromVal (condition->operand.valOperand))
2821 if (tree->trueLabel)
2822 geniCodeGoto (tree->trueLabel);
2828 if (tree->falseLabel)
2829 geniCodeGoto (tree->falseLabel);
2836 if (tree->trueLabel)
2838 ic = newiCodeCondition (condition,
2843 if (tree->falseLabel)
2844 geniCodeGoto (tree->falseLabel);
2848 ic = newiCodeCondition (condition,
2855 ast2iCode (tree->right,lvl+1);
2858 /*-----------------------------------------------------------------*/
2859 /* geniCodeJumpTable - tries to create a jump table for switch */
2860 /*-----------------------------------------------------------------*/
2862 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2864 int min = 0, max = 0, t, cnt = 0;
2871 if (!tree || !caseVals)
2874 /* the criteria for creating a jump table is */
2875 /* all integer numbers between the maximum & minimum must */
2876 /* be present , the maximum value should not exceed 255 */
2877 min = max = (int) floatFromVal (vch = caseVals);
2878 sprintf (buffer, "_case_%d_%d",
2879 tree->values.switchVals.swNum,
2881 addSet (&labels, newiTempLabel (buffer));
2883 /* if there is only one case value then no need */
2884 if (!(vch = vch->next))
2889 if (((t = (int) floatFromVal (vch)) - max) != 1)
2891 sprintf (buffer, "_case_%d_%d",
2892 tree->values.switchVals.swNum,
2894 addSet (&labels, newiTempLabel (buffer));
2900 /* if the number of case statements <= 2 then */
2901 /* it is not economical to create the jump table */
2902 /* since two compares are needed for boundary conditions */
2903 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2906 if (tree->values.switchVals.swDefault)
2907 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2909 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2911 falseLabel = newiTempLabel (buffer);
2913 /* so we can create a jumptable */
2914 /* first we rule out the boundary conditions */
2915 /* if only optimization says so */
2916 if (!optimize.noJTabBoundary)
2918 sym_link *cetype = getSpec (operandType (cond));
2919 /* no need to check the lower bound if
2920 the condition is unsigned & minimum value is zero */
2921 if (!(min == 0 && SPEC_USIGN (cetype)))
2923 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2924 ic = newiCodeCondition (boundary, falseLabel, NULL);
2928 /* now for upper bounds */
2929 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
2930 ic = newiCodeCondition (boundary, falseLabel, NULL);
2934 /* if the min is not zero then we no make it zero */
2937 cond = geniCodeSubtract (cond, operandFromLit (min));
2938 setOperandType (cond, UCHARTYPE);
2941 /* now create the jumptable */
2942 ic = newiCode (JUMPTABLE, NULL, NULL);
2943 IC_JTCOND (ic) = cond;
2944 IC_JTLABELS (ic) = labels;
2949 /*-----------------------------------------------------------------*/
2950 /* geniCodeSwitch - changes a switch to a if statement */
2951 /*-----------------------------------------------------------------*/
2953 geniCodeSwitch (ast * tree,int lvl)
2956 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
2957 value *caseVals = tree->values.switchVals.swVals;
2958 symbol *trueLabel, *falseLabel;
2960 /* if we can make this a jump table */
2961 if (geniCodeJumpTable (cond, caseVals, tree))
2962 goto jumpTable; /* no need for the comparison */
2964 /* for the cases defined do */
2968 operand *compare = geniCodeLogic (cond,
2969 operandFromValue (caseVals),
2972 sprintf (buffer, "_case_%d_%d",
2973 tree->values.switchVals.swNum,
2974 (int) floatFromVal (caseVals));
2975 trueLabel = newiTempLabel (buffer);
2977 ic = newiCodeCondition (compare, trueLabel, NULL);
2979 caseVals = caseVals->next;
2984 /* if default is present then goto break else break */
2985 if (tree->values.switchVals.swDefault)
2986 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2988 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2990 falseLabel = newiTempLabel (buffer);
2991 geniCodeGoto (falseLabel);
2994 ast2iCode (tree->right,lvl+1);
2997 /*-----------------------------------------------------------------*/
2998 /* geniCodeInline - intermediate code for inline assembler */
2999 /*-----------------------------------------------------------------*/
3001 geniCodeInline (ast * tree)
3005 ic = newiCode (INLINEASM, NULL, NULL);
3006 IC_INLINE (ic) = tree->values.inlineasm;
3010 /*-----------------------------------------------------------------*/
3011 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3012 /* particular case. Ie : assigning or dereferencing array or ptr */
3013 /*-----------------------------------------------------------------*/
3014 set * lvaluereqSet = NULL;
3015 typedef struct lvalItem
3022 /*-----------------------------------------------------------------*/
3023 /* addLvaluereq - add a flag for lvalreq for current ast level */
3024 /*-----------------------------------------------------------------*/
3025 void addLvaluereq(int lvl)
3027 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3030 addSetHead(&lvaluereqSet,lpItem);
3033 /*-----------------------------------------------------------------*/
3034 /* delLvaluereq - del a flag for lvalreq for current ast level */
3035 /*-----------------------------------------------------------------*/
3039 lpItem = getSet(&lvaluereqSet);
3040 if(lpItem) free(lpItem);
3042 /*-----------------------------------------------------------------*/
3043 /* clearLvaluereq - clear lvalreq flag */
3044 /*-----------------------------------------------------------------*/
3045 void clearLvaluereq()
3048 lpItem = peekSet(lvaluereqSet);
3049 if(lpItem) lpItem->req = 0;
3051 /*-----------------------------------------------------------------*/
3052 /* getLvaluereq - get the last lvalreq level */
3053 /*-----------------------------------------------------------------*/
3054 int getLvaluereqLvl()
3057 lpItem = peekSet(lvaluereqSet);
3058 if(lpItem) return lpItem->lvl;
3061 /*-----------------------------------------------------------------*/
3062 /* isLvaluereq - is lvalreq valid for this level ? */
3063 /*-----------------------------------------------------------------*/
3064 int isLvaluereq(int lvl)
3067 lpItem = peekSet(lvaluereqSet);
3068 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3072 /*-----------------------------------------------------------------*/
3073 /* ast2iCode - creates an icodeList from an ast */
3074 /*-----------------------------------------------------------------*/
3076 ast2iCode (ast * tree,int lvl)
3078 operand *left = NULL;
3079 operand *right = NULL;
3082 /* set the global variables for filename & line number */
3084 filename = tree->filename;
3086 lineno = tree->lineno;
3088 block = tree->block;
3090 scopeLevel = tree->level;
3092 if (tree->type == EX_VALUE)
3093 return operandFromValue (tree->opval.val);
3095 if (tree->type == EX_LINK)
3096 return operandFromLink (tree->opval.lnk);
3098 /* if we find a nullop */
3099 if (tree->type == EX_OP &&
3100 (tree->opval.op == NULLOP ||
3101 tree->opval.op == BLOCK))
3103 ast2iCode (tree->left,lvl+1);
3104 ast2iCode (tree->right,lvl+1);
3108 /* special cases for not evaluating */
3109 if (tree->opval.op != ':' &&
3110 tree->opval.op != '?' &&
3111 tree->opval.op != CALL &&
3112 tree->opval.op != IFX &&
3113 tree->opval.op != LABEL &&
3114 tree->opval.op != GOTO &&
3115 tree->opval.op != SWITCH &&
3116 tree->opval.op != FUNCTION &&
3117 tree->opval.op != INLINEASM)
3120 if (IS_ASSIGN_OP (tree->opval.op) ||
3121 IS_DEREF_OP (tree) ||
3122 (tree->opval.op == '&' && !tree->right) ||
3123 tree->opval.op == PTR_OP)
3126 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3127 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3130 left = operandFromAst (tree->left,lvl);
3132 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3133 left = geniCodeRValue (left, TRUE);
3137 left = operandFromAst (tree->left,lvl);
3139 if (tree->opval.op == INC_OP ||
3140 tree->opval.op == DEC_OP)
3143 right = operandFromAst (tree->right,lvl);
3148 right = operandFromAst (tree->right,lvl);
3152 /* now depending on the type of operand */
3153 /* this will be a biggy */
3154 switch (tree->opval.op)
3157 case '[': /* array operation */
3159 sym_link *ltype = operandType (left);
3160 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3161 right = geniCodeRValue (right, TRUE);
3164 return geniCodeArray (left, right,lvl);
3166 case '.': /* structure dereference */
3167 if (IS_PTR (operandType (left)))
3168 left = geniCodeRValue (left, TRUE);
3170 left = geniCodeRValue (left, FALSE);
3172 return geniCodeStruct (left, right, tree->lvalue);
3174 case PTR_OP: /* structure pointer dereference */
3177 pType = operandType (left);
3178 left = geniCodeRValue (left, TRUE);
3180 setOClass (pType, getSpec (operandType (left)));
3183 return geniCodeStruct (left, right, tree->lvalue);
3185 case INC_OP: /* increment operator */
3187 return geniCodePostInc (left);
3189 return geniCodePreInc (right);
3191 case DEC_OP: /* decrement operator */
3193 return geniCodePostDec (left);
3195 return geniCodePreDec (right);
3197 case '&': /* bitwise and or address of operator */
3199 { /* this is a bitwise operator */
3200 left = geniCodeRValue (left, FALSE);
3201 right = geniCodeRValue (right, FALSE);
3202 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3205 return geniCodeAddressOf (left);
3207 case '|': /* bitwise or & xor */
3209 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3210 geniCodeRValue (right, FALSE),
3215 return geniCodeDivision (geniCodeRValue (left, FALSE),
3216 geniCodeRValue (right, FALSE));
3219 return geniCodeModulus (geniCodeRValue (left, FALSE),
3220 geniCodeRValue (right, FALSE));
3223 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3224 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3226 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3230 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3231 geniCodeRValue (right, FALSE));
3233 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3237 return geniCodeAdd (geniCodeRValue (left, FALSE),
3238 geniCodeRValue (right, FALSE),lvl);
3240 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3243 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3244 geniCodeRValue (right, FALSE));
3247 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3248 geniCodeRValue (right, FALSE));
3250 return geniCodeCast (operandType (left),
3251 geniCodeRValue (right, FALSE), FALSE);
3257 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3261 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3262 setOperandType (op, UCHARTYPE);
3273 return geniCodeLogic (geniCodeRValue (left, FALSE),
3274 geniCodeRValue (right, FALSE),
3277 return geniCodeConditional (tree,lvl);
3280 return operandFromLit (getSize (tree->right->ftype));
3284 sym_link *rtype = operandType (right);
3285 sym_link *ltype = operandType (left);
3286 if (IS_PTR (rtype) && IS_ITEMP (right)
3287 && right->isaddr && compareType (rtype->next, ltype) == 1)
3288 right = geniCodeRValue (right, TRUE);
3290 right = geniCodeRValue (right, FALSE);
3292 geniCodeAssign (left, right, 0);
3297 geniCodeAssign (left,
3298 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3300 geniCodeRValue (right, FALSE),FALSE), 0);
3304 geniCodeAssign (left,
3305 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3307 geniCodeRValue (right, FALSE)), 0);
3310 geniCodeAssign (left,
3311 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3313 geniCodeRValue (right, FALSE)), 0);
3316 sym_link *rtype = operandType (right);
3317 sym_link *ltype = operandType (left);
3318 if (IS_PTR (rtype) && IS_ITEMP (right)
3319 && right->isaddr && compareType (rtype->next, ltype) == 1)
3320 right = geniCodeRValue (right, TRUE);
3322 right = geniCodeRValue (right, FALSE);
3325 return geniCodeAssign (left,
3326 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3332 sym_link *rtype = operandType (right);
3333 sym_link *ltype = operandType (left);
3334 if (IS_PTR (rtype) && IS_ITEMP (right)
3335 && right->isaddr && compareType (rtype->next, ltype) == 1)
3337 right = geniCodeRValue (right, TRUE);
3341 right = geniCodeRValue (right, FALSE);
3344 geniCodeAssign (left,
3345 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3351 geniCodeAssign (left,
3352 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3354 geniCodeRValue (right, FALSE)), 0);
3357 geniCodeAssign (left,
3358 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3360 geniCodeRValue (right, FALSE)), 0);
3363 geniCodeAssign (left,
3364 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3366 geniCodeRValue (right, FALSE),
3368 operandType (left)), 0);
3371 geniCodeAssign (left,
3372 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3374 geniCodeRValue (right, FALSE),
3376 operandType (left)), 0);
3379 geniCodeAssign (left,
3380 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3382 geniCodeRValue (right, FALSE),
3384 operandType (left)), 0);
3386 return geniCodeRValue (right, FALSE);
3389 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3392 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3393 return ast2iCode (tree->right,lvl+1);
3396 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3397 return ast2iCode (tree->right,lvl+1);
3400 geniCodeFunctionBody (tree,lvl);
3404 geniCodeReturn (right);
3408 geniCodeIfx (tree,lvl);
3412 geniCodeSwitch (tree,lvl);
3416 geniCodeInline (tree);
3423 /*-----------------------------------------------------------------*/
3424 /* reverseICChain - gets from the list and creates a linkedlist */
3425 /*-----------------------------------------------------------------*/
3432 while ((loop = getSet (&iCodeChain)))
3444 /*-----------------------------------------------------------------*/
3445 /* iCodeFromAst - given an ast will convert it to iCode */
3446 /*-----------------------------------------------------------------*/
3448 iCodeFromAst (ast * tree)
3450 returnLabel = newiTempLabel ("_return");
3451 entryLabel = newiTempLabel ("_entry");
3453 return reverseiCChain ();