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}", /*{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
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->noSpilLoc = op->noSpilLoc;
1093 nop->usesDefs = op->usesDefs;
1094 nop->isParm = op->isParm;
1098 /*-----------------------------------------------------------------*/
1099 /* operand from operand - creates an operand holder for the type */
1100 /*-----------------------------------------------------------------*/
1102 operandFromOperand (operand * op)
1108 nop = newOperand ();
1109 nop->type = op->type;
1110 nop->isaddr = op->isaddr;
1112 nop->isvolatile = op->isvolatile;
1113 nop->isGlobal = op->isGlobal;
1114 nop->isLiteral = op->isLiteral;
1115 nop->noSpilLoc = op->noSpilLoc;
1116 nop->usesDefs = op->usesDefs;
1117 nop->isParm = op->isParm;
1122 nop->operand.symOperand = op->operand.symOperand;
1125 nop->operand.valOperand = op->operand.valOperand;
1128 nop->operand.typeOperand = op->operand.typeOperand;
1135 /*-----------------------------------------------------------------*/
1136 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1137 /*-----------------------------------------------------------------*/
1139 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1141 operand *nop = operandFromOperand (op);
1143 if (nop->type == SYMBOL)
1145 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1146 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1152 /*-----------------------------------------------------------------*/
1153 /* operandFromSymbol - creates an operand from a symbol */
1154 /*-----------------------------------------------------------------*/
1156 operandFromSymbol (symbol * sym)
1161 /* if the symbol's type is a literal */
1162 /* then it is an enumerator type */
1163 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1164 return operandFromValue (valFromType (sym->etype));
1167 sym->key = ++operandKey;
1169 /* if this an implicit variable, means struct/union */
1170 /* member so just return it */
1171 if (sym->implicit || IS_FUNC (sym->type))
1175 op->operand.symOperand = sym;
1177 op->isvolatile = isOperandVolatile (op, TRUE);
1178 op->isGlobal = isOperandGlobal (op);
1182 /* under the following conditions create a
1183 register equivalent for a local symbol */
1184 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1185 (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) &&
1186 options.stackAuto == 0)
1189 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1190 !IS_FUNC (sym->type) && /* not a function */
1191 !sym->_isparm && /* not a parameter */
1192 sym->level && /* is a local variable */
1193 !sym->addrtaken && /* whose address has not been taken */
1194 !sym->reqv && /* does not already have a register euivalence */
1195 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1196 !IS_STATIC (sym->etype) && /* and not declared static */
1197 !sym->islbl && /* not a label */
1198 ok && /* farspace check */
1199 !IS_BITVAR (sym->etype) /* not a bit variable */
1203 /* we will use it after all optimizations
1204 and before liveRange calculation */
1205 sym->reqv = newiTempOperand (sym->type, 0);
1206 sym->reqv->key = sym->key;
1207 OP_SYMBOL (sym->reqv)->key = sym->key;
1208 OP_SYMBOL (sym->reqv)->isreqv = 1;
1209 OP_SYMBOL (sym->reqv)->islocal = 1;
1210 SPIL_LOC (sym->reqv) = sym;
1213 if (!IS_AGGREGATE (sym->type))
1217 op->operand.symOperand = sym;
1220 op->isvolatile = isOperandVolatile (op, TRUE);
1221 op->isGlobal = isOperandGlobal (op);
1222 op->isPtr = IS_PTR (operandType (op));
1223 op->isParm = sym->_isparm;
1228 /* itemp = &[_symbol] */
1230 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1231 IC_LEFT (ic)->type = SYMBOL;
1232 IC_LEFT (ic)->operand.symOperand = sym;
1233 IC_LEFT (ic)->key = sym->key;
1234 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1235 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1236 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1239 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1240 if (IS_ARRAY (sym->type))
1242 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1243 IC_RESULT (ic)->isaddr = 0;
1246 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1248 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1252 return IC_RESULT (ic);
1255 /*-----------------------------------------------------------------*/
1256 /* operandFromValue - creates an operand from value */
1257 /*-----------------------------------------------------------------*/
1259 operandFromValue (value * val)
1263 /* if this is a symbol then do the symbol thing */
1265 return operandFromSymbol (val->sym);
1267 /* this is not a symbol */
1270 op->operand.valOperand = val;
1271 op->isLiteral = isOperandLiteral (op);
1275 /*-----------------------------------------------------------------*/
1276 /* operandFromLink - operand from typeChain */
1277 /*-----------------------------------------------------------------*/
1279 operandFromLink (sym_link * type)
1283 /* operand from sym_link */
1289 op->operand.typeOperand = copyLinkChain (type);
1293 /*-----------------------------------------------------------------*/
1294 /* operandFromLit - makes an operand from a literal value */
1295 /*-----------------------------------------------------------------*/
1297 operandFromLit (double i)
1299 return operandFromValue (valueFromLit (i));
1302 /*-----------------------------------------------------------------*/
1303 /* operandFromAst - creates an operand from an ast */
1304 /*-----------------------------------------------------------------*/
1306 operandFromAst (ast * tree,int lvl)
1312 /* depending on type do */
1316 return ast2iCode (tree,lvl+1);
1320 return operandFromValue (tree->opval.val);
1324 return operandFromLink (tree->opval.lnk);
1328 /* Just to keep the comiler happy */
1329 return (operand *) 0;
1332 /*-----------------------------------------------------------------*/
1333 /* setOperandType - sets the operand's type to the given type */
1334 /*-----------------------------------------------------------------*/
1336 setOperandType (operand * op, sym_link * type)
1338 /* depending on the type of operand */
1343 op->operand.valOperand->etype =
1344 getSpec (op->operand.valOperand->type =
1345 copyLinkChain (type));
1349 if (op->operand.symOperand->isitmp)
1350 op->operand.symOperand->etype =
1351 getSpec (op->operand.symOperand->type =
1352 copyLinkChain (type));
1354 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1355 "attempt to modify type of source");
1359 op->operand.typeOperand = copyLinkChain (type);
1364 /*-----------------------------------------------------------------*/
1365 /* Get size in byte of ptr need to access an array */
1366 /*-----------------------------------------------------------------*/
1368 getArraySizePtr (operand * op)
1370 sym_link *ltype = operandType(op);
1374 int size = getSize(ltype);
1375 return(IS_GENPTR(ltype)?(size-1):size);
1380 sym_link *letype = getSpec(ltype);
1381 switch (PTR_TYPE (SPEC_OCLS (letype)))
1393 return (GPTRSIZE-1);
1402 /*-----------------------------------------------------------------*/
1403 /* perform "usual unary conversions" */
1404 /*-----------------------------------------------------------------*/
1406 usualUnaryConversions (operand * op)
1408 if (IS_INTEGRAL (operandType (op)))
1410 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1413 return geniCodeCast (INTTYPE, op, TRUE);
1419 /*-----------------------------------------------------------------*/
1420 /* perform "usual binary conversions" */
1421 /*-----------------------------------------------------------------*/
1423 usualBinaryConversions (operand ** op1, operand ** op2)
1426 sym_link *rtype = operandType (*op2);
1427 sym_link *ltype = operandType (*op1);
1429 ctype = computeType (ltype, rtype);
1430 *op1 = geniCodeCast (ctype, *op1, TRUE);
1431 *op2 = geniCodeCast (ctype, *op2, TRUE);
1436 /*-----------------------------------------------------------------*/
1437 /* geniCodeValueAtAddress - generate intermeditate code for value */
1439 /*-----------------------------------------------------------------*/
1441 geniCodeRValue (operand * op, bool force)
1444 sym_link *type = operandType (op);
1445 sym_link *etype = getSpec (type);
1447 /* if this is an array & already */
1448 /* an address then return this */
1449 if (IS_AGGREGATE (type) ||
1450 (IS_PTR (type) && !force && !op->isaddr))
1451 return operandFromOperand (op);
1453 /* if this is not an address then must be */
1454 /* rvalue already so return this one */
1458 /* if this is not a temp symbol then */
1459 if (!IS_ITEMP (op) &&
1461 !IN_FARSPACE (SPEC_OCLS (etype)))
1463 op = operandFromOperand (op);
1468 if (IS_SPEC (type) &&
1469 IS_TRUE_SYMOP (op) &&
1470 (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
1472 op = operandFromOperand (op);
1477 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1478 if (IS_PTR (type) && op->isaddr && force)
1481 type = copyLinkChain (type);
1483 IC_RESULT (ic) = newiTempOperand (type, 1);
1484 IC_RESULT (ic)->isaddr = 0;
1486 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1488 /* if the right is a symbol */
1489 if (op->type == SYMBOL)
1490 IC_RESULT (ic)->operand.symOperand->args =
1491 op->operand.symOperand->args;
1494 return IC_RESULT (ic);
1497 /*-----------------------------------------------------------------*/
1498 /* geniCodeCast - changes the value from one type to another */
1499 /*-----------------------------------------------------------------*/
1501 geniCodeCast (sym_link * type, operand * op, bool implicit)
1505 sym_link *opetype = getSpec (optype = operandType (op));
1508 /* one of them has size zero then error */
1509 if (IS_VOID (optype))
1511 werror (E_CAST_ZERO);
1515 /* if the operand is already the desired type then do nothing */
1516 if (compareType (type, optype) == 1)
1519 /* if this is a literal then just change the type & return */
1520 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1521 return operandFromValue (valCastLiteral (type,
1522 operandLitValue (op)));
1524 /* if casting to some pointer type &&
1525 the destination is not a generic pointer
1526 then give a warning : (only for implicit casts) */
1527 if (IS_PTR (optype) && implicit &&
1528 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1531 werror (E_INCOMPAT_CAST);
1532 fprintf (stderr, "from type '");
1533 printTypeChain (optype, stderr);
1534 fprintf (stderr, "' to type '");
1535 printTypeChain (type, stderr);
1536 fprintf (stderr, "'\n");
1539 /* if they are the same size create an assignment */
1540 if (getSize (type) == getSize (optype) &&
1541 !IS_BITFIELD (type) &&
1543 !IS_FLOAT (optype) &&
1544 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1545 (!IS_SPEC (type) && !IS_SPEC (optype))))
1548 ic = newiCode ('=', NULL, op);
1549 IC_RESULT (ic) = newiTempOperand (type, 0);
1550 SPIL_LOC (IC_RESULT (ic)) =
1551 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1552 IC_RESULT (ic)->isaddr = 0;
1556 ic = newiCode (CAST, operandFromLink (type),
1557 geniCodeRValue (op, FALSE));
1559 IC_RESULT (ic) = newiTempOperand (type, 0);
1562 /* preserve the storage class & output class */
1563 /* of the original variable */
1564 restype = getSpec (operandType (IC_RESULT (ic)));
1565 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1566 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1569 return IC_RESULT (ic);
1572 /*-----------------------------------------------------------------*/
1573 /* geniCodeLabel - will create a Label */
1574 /*-----------------------------------------------------------------*/
1576 geniCodeLabel (symbol * label)
1580 ic = newiCodeLabelGoto (LABEL, label);
1584 /*-----------------------------------------------------------------*/
1585 /* geniCodeGoto - will create a Goto */
1586 /*-----------------------------------------------------------------*/
1588 geniCodeGoto (symbol * label)
1592 ic = newiCodeLabelGoto (GOTO, label);
1596 /*-----------------------------------------------------------------*/
1597 /* geniCodeMultiply - gen intermediate code for multiplication */
1598 /*-----------------------------------------------------------------*/
1600 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1607 /* if they are both literal then we know the result */
1608 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1609 return operandFromValue (valMult (left->operand.valOperand,
1610 right->operand.valOperand));
1612 if (IS_LITERAL(retype)) {
1613 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1616 resType = usualBinaryConversions (&left, &right);
1618 rtype = operandType (right);
1619 retype = getSpec (rtype);
1620 ltype = operandType (left);
1621 letype = getSpec (ltype);
1625 SPEC_NOUN(getSpec(resType))=V_INT;
1628 /* if the right is a literal & power of 2 */
1629 /* then make it a left shift */
1630 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1631 efficient in most cases than 2 bytes result = 2 bytes << literal
1632 if port has 1 byte muldiv */
1633 if (p2 && !IS_FLOAT (letype) &&
1634 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1635 (port->support.muldiv == 1)))
1637 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1639 /* LEFT_OP need same size for left and result, */
1640 left = geniCodeCast (resType, left, TRUE);
1641 ltype = operandType (left);
1643 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1647 ic = newiCode ('*', left, right); /* normal multiplication */
1648 /* if the size left or right > 1 then support routine */
1649 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1653 IC_RESULT (ic) = newiTempOperand (resType, 1);
1656 return IC_RESULT (ic);
1659 /*-----------------------------------------------------------------*/
1660 /* geniCodeDivision - gen intermediate code for division */
1661 /*-----------------------------------------------------------------*/
1663 geniCodeDivision (operand * left, operand * right)
1668 sym_link *rtype = operandType (right);
1669 sym_link *retype = getSpec (rtype);
1670 sym_link *ltype = operandType (left);
1671 sym_link *letype = getSpec (ltype);
1673 resType = usualBinaryConversions (&left, &right);
1675 /* if the right is a literal & power of 2 */
1676 /* then make it a right shift */
1677 if (IS_LITERAL (retype) &&
1678 !IS_FLOAT (letype) &&
1679 (p2 = powof2 ((unsigned long)
1680 floatFromVal (right->operand.valOperand)))) {
1681 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1685 ic = newiCode ('/', left, right); /* normal division */
1686 /* if the size left or right > 1 then support routine */
1687 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1690 IC_RESULT (ic) = newiTempOperand (resType, 0);
1693 return IC_RESULT (ic);
1695 /*-----------------------------------------------------------------*/
1696 /* geniCodeModulus - gen intermediate code for modulus */
1697 /*-----------------------------------------------------------------*/
1699 geniCodeModulus (operand * left, operand * right)
1705 /* if they are both literal then we know the result */
1706 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1707 return operandFromValue (valMod (left->operand.valOperand,
1708 right->operand.valOperand));
1710 resType = usualBinaryConversions (&left, &right);
1712 /* now they are the same size */
1713 ic = newiCode ('%', left, right);
1715 /* if the size left or right > 1 then support routine */
1716 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1718 IC_RESULT (ic) = newiTempOperand (resType, 0);
1721 return IC_RESULT (ic);
1724 /*-----------------------------------------------------------------*/
1725 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1726 /*-----------------------------------------------------------------*/
1728 geniCodePtrPtrSubtract (operand * left, operand * right)
1734 /* if they are both literals then */
1735 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1737 result = operandFromValue (valMinus (left->operand.valOperand,
1738 right->operand.valOperand));
1742 ic = newiCode ('-', left, right);
1744 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1748 return geniCodeDivision (result,
1749 operandFromLit (getSize (ltype->next)));
1752 /*-----------------------------------------------------------------*/
1753 /* geniCodeSubtract - generates code for subtraction */
1754 /*-----------------------------------------------------------------*/
1756 geniCodeSubtract (operand * left, operand * right)
1763 /* if they both pointers then */
1764 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1765 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1766 return geniCodePtrPtrSubtract (left, right);
1768 /* if they are both literal then we know the result */
1769 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1770 && left->isLiteral && right->isLiteral)
1771 return operandFromValue (valMinus (left->operand.valOperand,
1772 right->operand.valOperand));
1774 /* if left is an array or pointer */
1775 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1777 isarray = left->isaddr;
1778 right = geniCodeMultiply (right,
1779 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1780 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1783 { /* make them the same size */
1784 resType = usualBinaryConversions (&left, &right);
1787 ic = newiCode ('-', left, right);
1789 IC_RESULT (ic) = newiTempOperand (resType, 1);
1790 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1792 /* if left or right is a float */
1793 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1797 return IC_RESULT (ic);
1800 /*-----------------------------------------------------------------*/
1801 /* geniCodeAdd - generates iCode for addition */
1802 /*-----------------------------------------------------------------*/
1804 geniCodeAdd (operand * left, operand * right,int lvl)
1812 /* if left is an array then array access */
1813 if (IS_ARRAY (ltype))
1814 return geniCodeArray (left, right,lvl);
1816 /* if the right side is LITERAL zero */
1817 /* return the left side */
1818 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1821 /* if left is literal zero return right */
1822 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1825 /* if left is an array or pointer then size */
1828 isarray = left->isaddr;
1829 // there is no need to multiply with 1
1830 if (getSize(ltype->next)!=1) {
1831 size = operandFromLit (getSize (ltype->next));
1832 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1834 resType = copyLinkChain (ltype);
1837 { /* make them the same size */
1838 resType = usualBinaryConversions (&left, &right);
1841 /* if they are both literals then we know */
1842 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1843 && left->isLiteral && right->isLiteral)
1844 return operandFromValue (valPlus (valFromType (letype),
1845 valFromType (retype)));
1847 ic = newiCode ('+', left, right);
1849 IC_RESULT (ic) = newiTempOperand (resType, 1);
1850 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1852 /* if left or right is a float then support
1854 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1859 return IC_RESULT (ic);
1863 /*-----------------------------------------------------------------*/
1864 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1865 /*-----------------------------------------------------------------*/
1867 aggrToPtr (sym_link * type, bool force)
1873 if (IS_PTR (type) && !force)
1876 etype = getSpec (type);
1880 /* if the output class is generic */
1881 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1882 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1884 /* if the variable was declared a constant */
1885 /* then the pointer points to a constant */
1886 if (IS_CONSTANT (etype))
1887 DCL_PTR_CONST (ptype) = 1;
1889 /* the variable was volatile then pointer to volatile */
1890 if (IS_VOLATILE (etype))
1891 DCL_PTR_VOLATILE (ptype) = 1;
1895 /*-----------------------------------------------------------------*/
1896 /* geniCodeArray2Ptr - array to pointer */
1897 /*-----------------------------------------------------------------*/
1899 geniCodeArray2Ptr (operand * op)
1901 sym_link *optype = operandType (op);
1902 sym_link *opetype = getSpec (optype);
1904 /* set the pointer depending on the storage class */
1905 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1906 DCL_PTR_CONST (optype) = port->mem.code_ro;
1909 /* if the variable was declared a constant */
1910 /* then the pointer points to a constant */
1911 if (IS_CONSTANT (opetype))
1912 DCL_PTR_CONST (optype) = 1;
1914 /* the variable was volatile then pointer to volatile */
1915 if (IS_VOLATILE (opetype))
1916 DCL_PTR_VOLATILE (optype) = 1;
1922 /*-----------------------------------------------------------------*/
1923 /* geniCodeArray - array access */
1924 /*-----------------------------------------------------------------*/
1926 geniCodeArray (operand * left, operand * right,int lvl)
1929 sym_link *ltype = operandType (left);
1933 if (IS_PTR (ltype->next) && left->isaddr)
1935 left = geniCodeRValue (left, FALSE);
1937 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
1940 right = geniCodeMultiply (right,
1941 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1943 /* we can check for limits here */
1944 if (isOperandLiteral (right) &&
1947 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
1949 werror (E_ARRAY_BOUND);
1950 right = operandFromLit (0);
1953 ic = newiCode ('+', left, right);
1955 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
1956 !IS_AGGREGATE (ltype->next) &&
1957 !IS_PTR (ltype->next))
1958 ? ltype : ltype->next), 0);
1960 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
1962 return IC_RESULT (ic);
1965 /*-----------------------------------------------------------------*/
1966 /* geniCodeStruct - generates intermediate code for structres */
1967 /*-----------------------------------------------------------------*/
1969 geniCodeStruct (operand * left, operand * right, bool islval)
1972 sym_link *type = operandType (left);
1973 sym_link *etype = getSpec (type);
1975 symbol *element = getStructElement (SPEC_STRUCT (etype),
1976 right->operand.symOperand);
1978 /* add the offset */
1979 ic = newiCode ('+', left, operandFromLit (element->offset));
1981 IC_RESULT (ic) = newiTempOperand (element->type, 0);
1983 /* preserve the storage & output class of the struct */
1984 /* as well as the volatile attribute */
1985 retype = getSpec (operandType (IC_RESULT (ic)));
1986 SPEC_SCLS (retype) = SPEC_SCLS (etype);
1987 SPEC_OCLS (retype) = SPEC_OCLS (etype);
1988 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
1990 if (IS_PTR (element->type))
1991 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1993 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
1997 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2000 /*-----------------------------------------------------------------*/
2001 /* geniCodePostInc - generate int code for Post increment */
2002 /*-----------------------------------------------------------------*/
2004 geniCodePostInc (operand * op)
2008 sym_link *optype = operandType (op);
2010 operand *rv = (IS_ITEMP (op) ?
2011 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2013 sym_link *rvtype = operandType (rv);
2016 /* if this is not an address we have trouble */
2019 werror (E_LVALUE_REQUIRED, "++");
2023 rOp = newiTempOperand (rvtype, 0);
2029 geniCodeAssign (rOp, rv, 0);
2031 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2032 if (IS_FLOAT (rvtype))
2033 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2035 ic = newiCode ('+', rv, operandFromLit (size));
2037 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2040 geniCodeAssign (op, result, 0);
2046 /*-----------------------------------------------------------------*/
2047 /* geniCodePreInc - generate code for preIncrement */
2048 /*-----------------------------------------------------------------*/
2050 geniCodePreInc (operand * op)
2053 sym_link *optype = operandType (op);
2054 operand *rop = (IS_ITEMP (op) ?
2055 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2057 sym_link *roptype = operandType (rop);
2063 werror (E_LVALUE_REQUIRED, "++");
2068 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2069 if (IS_FLOAT (roptype))
2070 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2072 ic = newiCode ('+', rop, operandFromLit (size));
2073 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2077 return geniCodeAssign (op, result, 0);
2080 /*-----------------------------------------------------------------*/
2081 /* geniCodePostDec - generates code for Post decrement */
2082 /*-----------------------------------------------------------------*/
2084 geniCodePostDec (operand * op)
2088 sym_link *optype = operandType (op);
2090 operand *rv = (IS_ITEMP (op) ?
2091 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2093 sym_link *rvtype = operandType (rv);
2096 /* if this is not an address we have trouble */
2099 werror (E_LVALUE_REQUIRED, "++");
2103 rOp = newiTempOperand (rvtype, 0);
2109 geniCodeAssign (rOp, rv, 0);
2111 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2112 if (IS_FLOAT (rvtype))
2113 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2115 ic = newiCode ('-', rv, operandFromLit (size));
2117 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2120 geniCodeAssign (op, result, 0);
2126 /*-----------------------------------------------------------------*/
2127 /* geniCodePreDec - generate code for pre decrement */
2128 /*-----------------------------------------------------------------*/
2130 geniCodePreDec (operand * op)
2133 sym_link *optype = operandType (op);
2134 operand *rop = (IS_ITEMP (op) ?
2135 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2137 sym_link *roptype = operandType (rop);
2143 werror (E_LVALUE_REQUIRED, "++");
2148 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2149 if (IS_FLOAT (roptype))
2150 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2152 ic = newiCode ('-', rop, operandFromLit (size));
2153 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2157 return geniCodeAssign (op, result, 0);
2161 /*-----------------------------------------------------------------*/
2162 /* geniCodeBitwise - gen int code for bitWise operators */
2163 /*-----------------------------------------------------------------*/
2165 geniCodeBitwise (operand * left, operand * right,
2166 int oper, sym_link * resType)
2170 left = geniCodeCast (resType, left, TRUE);
2171 right = geniCodeCast (resType, right, TRUE);
2173 ic = newiCode (oper, left, right);
2174 IC_RESULT (ic) = newiTempOperand (resType, 0);
2177 return IC_RESULT (ic);
2180 /*-----------------------------------------------------------------*/
2181 /* geniCodeAddressOf - gens icode for '&' address of operator */
2182 /*-----------------------------------------------------------------*/
2184 geniCodeAddressOf (operand * op)
2188 sym_link *optype = operandType (op);
2189 sym_link *opetype = getSpec (optype);
2191 /* lvalue check already done in decorateType */
2192 /* this must be a lvalue */
2193 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2194 /* werror (E_LVALUE_REQUIRED,"&"); */
2199 p->class = DECLARATOR;
2201 /* set the pointer depending on the storage class */
2202 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2203 DCL_PTR_CONST (p) = port->mem.code_ro;
2205 /* make sure we preserve the const & volatile */
2206 if (IS_CONSTANT (opetype))
2207 DCL_PTR_CONST (p) = 1;
2209 if (IS_VOLATILE (opetype))
2210 DCL_PTR_VOLATILE (p) = 1;
2212 p->next = copyLinkChain (optype);
2214 /* if already a temp */
2217 setOperandType (op, p);
2222 /* other wise make this of the type coming in */
2223 ic = newiCode (ADDRESS_OF, op, NULL);
2224 IC_RESULT (ic) = newiTempOperand (p, 1);
2225 IC_RESULT (ic)->isaddr = 0;
2227 return IC_RESULT (ic);
2229 /*-----------------------------------------------------------------*/
2230 /* setOClass - sets the output class depending on the pointer type */
2231 /*-----------------------------------------------------------------*/
2233 setOClass (sym_link * ptr, sym_link * spec)
2235 switch (DCL_TYPE (ptr))
2238 SPEC_OCLS (spec) = data;
2242 SPEC_OCLS (spec) = generic;
2246 SPEC_OCLS (spec) = xdata;
2250 SPEC_OCLS (spec) = code;
2254 SPEC_OCLS (spec) = idata;
2258 SPEC_OCLS (spec) = xstack;
2262 SPEC_OCLS (spec) = eeprom;
2271 /*-----------------------------------------------------------------*/
2272 /* geniCodeDerefPtr - dereference pointer with '*' */
2273 /*-----------------------------------------------------------------*/
2275 geniCodeDerefPtr (operand * op,int lvl)
2277 sym_link *rtype, *retype;
2278 sym_link *optype = operandType (op);
2280 /* if this is a pointer then generate the rvalue */
2281 if (IS_PTR (optype))
2283 if (IS_TRUE_SYMOP (op))
2286 op = geniCodeRValue (op, TRUE);
2289 op = geniCodeRValue (op, TRUE);
2292 /* now get rid of the pointer part */
2293 if (isLvaluereq(lvl) && IS_ITEMP (op))
2295 retype = getSpec (rtype = copyLinkChain (optype));
2299 retype = getSpec (rtype = copyLinkChain (optype->next));
2302 /* if this is a pointer then outputclass needs 2b updated */
2303 if (IS_PTR (optype))
2304 setOClass (optype, retype);
2306 op->isGptr = IS_GENPTR (optype);
2308 /* if the pointer was declared as a constant */
2309 /* then we cannot allow assignment to the derefed */
2310 if (IS_PTR_CONST (optype))
2311 SPEC_CONST (retype) = 1;
2313 op->isaddr = (IS_PTR (rtype) ||
2314 IS_STRUCT (rtype) ||
2319 if (!isLvaluereq(lvl))
2320 op = geniCodeRValue (op, TRUE);
2322 setOperandType (op, rtype);
2327 /*-----------------------------------------------------------------*/
2328 /* geniCodeUnaryMinus - does a unary minus of the operand */
2329 /*-----------------------------------------------------------------*/
2331 geniCodeUnaryMinus (operand * op)
2334 sym_link *optype = operandType (op);
2336 if (IS_LITERAL (optype))
2337 return operandFromLit (-floatFromVal (op->operand.valOperand));
2339 ic = newiCode (UNARYMINUS, op, NULL);
2340 IC_RESULT (ic) = newiTempOperand (optype, 0);
2342 return IC_RESULT (ic);
2345 /*-----------------------------------------------------------------*/
2346 /* geniCodeLeftShift - gen i code for left shift */
2347 /*-----------------------------------------------------------------*/
2349 geniCodeLeftShift (operand * left, operand * right)
2353 ic = newiCode (LEFT_OP, left, right);
2354 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2356 return IC_RESULT (ic);
2359 /*-----------------------------------------------------------------*/
2360 /* geniCodeRightShift - gen i code for right shift */
2361 /*-----------------------------------------------------------------*/
2363 geniCodeRightShift (operand * left, operand * right)
2367 ic = newiCode (RIGHT_OP, left, right);
2368 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2370 return IC_RESULT (ic);
2373 #if defined(__BORLANDC__) || defined(_MSC_VER)
2374 #define LONG_LONG __int64
2376 #define LONG_LONG long long
2379 /*-----------------------------------------------------------------*/
2380 /* geniCodeLogic- logic code */
2381 /*-----------------------------------------------------------------*/
2383 geniCodeLogic (operand * left, operand * right, int op)
2387 sym_link *rtype = operandType (right);
2388 sym_link *ltype = operandType (left);
2390 /* left is integral type and right is literal then
2391 check if the literal value is within bounds */
2392 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2394 int nbits = bitsForType (ltype);
2395 long v = (long) operandLitValue (right);
2397 if (v >= ((LONG_LONG) 1 << nbits) && v > 0)
2398 werror (W_CONST_RANGE, " compare operation ");
2401 ctype = usualBinaryConversions (&left, &right);
2403 ic = newiCode (op, left, right);
2404 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2406 /* if comparing float
2407 and not a '==' || '!=' || '&&' || '||' (these
2409 if (IS_FLOAT(ctype) &&
2417 return IC_RESULT (ic);
2420 /*-----------------------------------------------------------------*/
2421 /* geniCodeUnary - for a a generic unary operation */
2422 /*-----------------------------------------------------------------*/
2424 geniCodeUnary (operand * op, int oper)
2426 iCode *ic = newiCode (oper, op, NULL);
2428 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2430 return IC_RESULT (ic);
2433 /*-----------------------------------------------------------------*/
2434 /* geniCodeConditional - geniCode for '?' ':' operation */
2435 /*-----------------------------------------------------------------*/
2437 geniCodeConditional (ast * tree,int lvl)
2440 symbol *falseLabel = newiTempLabel (NULL);
2441 symbol *exitLabel = newiTempLabel (NULL);
2442 operand *cond = ast2iCode (tree->left,lvl+1);
2443 operand *true, *false, *result;
2445 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2449 true = ast2iCode (tree->right->left,lvl+1);
2451 /* move the value to a new Operand */
2452 result = newiTempOperand (operandType (true), 0);
2453 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2455 /* generate an unconditional goto */
2456 geniCodeGoto (exitLabel);
2458 /* now for the right side */
2459 geniCodeLabel (falseLabel);
2461 false = ast2iCode (tree->right->right,lvl+1);
2462 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2464 /* create the exit label */
2465 geniCodeLabel (exitLabel);
2470 /*-----------------------------------------------------------------*/
2471 /* geniCodeAssign - generate code for assignment */
2472 /*-----------------------------------------------------------------*/
2474 geniCodeAssign (operand * left, operand * right, int nosupdate)
2477 sym_link *ltype = operandType (left);
2478 sym_link *rtype = operandType (right);
2480 if (!left->isaddr && !IS_ITEMP (left))
2482 werror (E_LVALUE_REQUIRED, "assignment");
2486 /* left is integral type and right is literal then
2487 check if the literal value is within bounds */
2488 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2490 int nbits = bitsForType (ltype);
2491 long v = (long) operandLitValue (right);
2493 if (v >= ((LONG_LONG) 1 << nbits) && v > 0)
2494 werror (W_CONST_RANGE, " = operation");
2497 /* if the left & right type don't exactly match */
2498 /* if pointer set then make sure the check is
2499 done with the type & not the pointer */
2500 /* then cast rights type to left */
2502 /* first check the type for pointer assignement */
2503 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2504 compareType (ltype, rtype) < 0)
2506 if (compareType (ltype->next, rtype) < 0)
2507 right = geniCodeCast (ltype->next, right, TRUE);
2509 else if (compareType (ltype, rtype) < 0)
2510 right = geniCodeCast (ltype, right, TRUE);
2512 /* if left is a true symbol & ! volatile
2513 create an assignment to temporary for
2514 the right & then assign this temporary
2515 to the symbol this is SSA . isn't it simple
2516 and folks have published mountains of paper on it */
2517 if (IS_TRUE_SYMOP (left) &&
2518 !isOperandVolatile (left, FALSE) &&
2519 isOperandGlobal (left))
2523 if (IS_TRUE_SYMOP (right))
2524 sym = OP_SYMBOL (right);
2525 ic = newiCode ('=', NULL, right);
2526 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2527 SPIL_LOC (right) = sym;
2531 ic = newiCode ('=', NULL, right);
2532 IC_RESULT (ic) = left;
2535 /* if left isgptr flag is set then support
2536 routine will be required */
2540 ic->nosupdate = nosupdate;
2544 /*-----------------------------------------------------------------*/
2545 /* geniCodeSEParms - generate code for side effecting fcalls */
2546 /*-----------------------------------------------------------------*/
2548 geniCodeSEParms (ast * parms,int lvl)
2553 if (parms->type == EX_OP && parms->opval.op == PARAM)
2555 geniCodeSEParms (parms->left,lvl);
2556 geniCodeSEParms (parms->right,lvl);
2560 /* hack don't like this but too lazy to think of
2562 if (IS_ADDRESS_OF_OP (parms))
2563 parms->left->lvalue = 1;
2565 if (IS_CAST_OP (parms) &&
2566 IS_PTR (parms->ftype) &&
2567 IS_ADDRESS_OF_OP (parms->right))
2568 parms->right->left->lvalue = 1;
2570 parms->opval.oprnd =
2571 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2573 parms->type = EX_OPERAND;
2576 /*-----------------------------------------------------------------*/
2577 /* geniCodeParms - generates parameters */
2578 /*-----------------------------------------------------------------*/
2580 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2588 /* if this is a param node then do the left & right */
2589 if (parms->type == EX_OP && parms->opval.op == PARAM)
2591 geniCodeParms (parms->left, stack, fetype, func,lvl);
2592 geniCodeParms (parms->right, stack, fetype, func,lvl);
2596 /* get the parameter value */
2597 if (parms->type == EX_OPERAND)
2598 pval = parms->opval.oprnd;
2601 /* maybe this else should go away ?? */
2602 /* hack don't like this but too lazy to think of
2604 if (IS_ADDRESS_OF_OP (parms))
2605 parms->left->lvalue = 1;
2607 if (IS_CAST_OP (parms) &&
2608 IS_PTR (parms->ftype) &&
2609 IS_ADDRESS_OF_OP (parms->right))
2610 parms->right->left->lvalue = 1;
2612 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2615 /* if register parm then make it a send */
2616 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2617 IS_REGPARM (parms->etype)) && !func->hasVargs)
2619 ic = newiCode (SEND, pval, NULL);
2624 /* now decide whether to push or assign */
2625 if (!(options.stackAuto || IS_RENT (fetype)))
2629 operand *top = operandFromSymbol (parms->argSym);
2630 geniCodeAssign (top, pval, 1);
2634 sym_link *p = operandType (pval);
2636 ic = newiCode (IPUSH, pval, NULL);
2638 /* update the stack adjustment */
2639 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2646 /*-----------------------------------------------------------------*/
2647 /* geniCodeCall - generates temp code for calling */
2648 /*-----------------------------------------------------------------*/
2650 geniCodeCall (operand * left, ast * parms,int lvl)
2654 sym_link *type, *etype;
2657 /* take care of parameters with side-effecting
2658 function calls in them, this is required to take care
2659 of overlaying function parameters */
2660 geniCodeSEParms (parms,lvl);
2662 /* first the parameters */
2663 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2665 /* now call : if symbol then pcall */
2666 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2667 ic = newiCode (PCALL, left, NULL);
2669 ic = newiCode (CALL, left, NULL);
2671 IC_ARGS (ic) = left->operand.symOperand->args;
2672 type = copyLinkChain (operandType (left)->next);
2673 etype = getSpec (type);
2674 SPEC_EXTR (etype) = 0;
2675 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2679 /* stack adjustment after call */
2680 ic->parmBytes = stack;
2685 /*-----------------------------------------------------------------*/
2686 /* geniCodeReceive - generate intermediate code for "receive" */
2687 /*-----------------------------------------------------------------*/
2689 geniCodeReceive (value * args)
2691 /* for all arguments that are passed in registers */
2695 if (IS_REGPARM (args->etype))
2697 operand *opr = operandFromValue (args);
2699 symbol *sym = OP_SYMBOL (opr);
2702 /* we will use it after all optimizations
2703 and before liveRange calculation */
2704 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2707 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2708 options.stackAuto == 0 &&
2714 opl = newiTempOperand (args->type, 0);
2716 sym->reqv->key = sym->key;
2717 OP_SYMBOL (sym->reqv)->key = sym->key;
2718 OP_SYMBOL (sym->reqv)->isreqv = 1;
2719 OP_SYMBOL (sym->reqv)->islocal = 0;
2720 SPIL_LOC (sym->reqv) = sym;
2724 ic = newiCode (RECEIVE, NULL, NULL);
2725 currFunc->recvSize = getSize (sym->etype);
2726 IC_RESULT (ic) = opr;
2734 /*-----------------------------------------------------------------*/
2735 /* geniCodeFunctionBody - create the function body */
2736 /*-----------------------------------------------------------------*/
2738 geniCodeFunctionBody (ast * tree,int lvl)
2745 /* reset the auto generation */
2751 func = ast2iCode (tree->left,lvl+1);
2752 fetype = getSpec (operandType (func));
2754 savelineno = lineno;
2755 lineno = OP_SYMBOL (func)->lineDef;
2756 /* create an entry label */
2757 geniCodeLabel (entryLabel);
2758 lineno = savelineno;
2760 /* create a proc icode */
2761 ic = newiCode (FUNCTION, func, NULL);
2762 /* if the function has parmas then */
2763 /* save the parameters information */
2764 ic->argLabel.args = tree->values.args;
2765 ic->lineno = OP_SYMBOL (func)->lineDef;
2769 /* for all parameters that are passed
2770 on registers add a "receive" */
2771 geniCodeReceive (tree->values.args);
2773 /* generate code for the body */
2774 ast2iCode (tree->right,lvl+1);
2776 /* create a label for return */
2777 geniCodeLabel (returnLabel);
2779 /* now generate the end proc */
2780 ic = newiCode (ENDFUNCTION, func, NULL);
2785 /*-----------------------------------------------------------------*/
2786 /* geniCodeReturn - gen icode for 'return' statement */
2787 /*-----------------------------------------------------------------*/
2789 geniCodeReturn (operand * op)
2793 /* if the operand is present force an rvalue */
2795 op = geniCodeRValue (op, FALSE);
2797 ic = newiCode (RETURN, op, NULL);
2801 /*-----------------------------------------------------------------*/
2802 /* geniCodeIfx - generates code for extended if statement */
2803 /*-----------------------------------------------------------------*/
2805 geniCodeIfx (ast * tree,int lvl)
2808 operand *condition = ast2iCode (tree->left,lvl+1);
2811 /* if condition is null then exit */
2815 condition = geniCodeRValue (condition, FALSE);
2817 cetype = getSpec (operandType (condition));
2818 /* if the condition is a literal */
2819 if (IS_LITERAL (cetype))
2821 if (floatFromVal (condition->operand.valOperand))
2823 if (tree->trueLabel)
2824 geniCodeGoto (tree->trueLabel);
2830 if (tree->falseLabel)
2831 geniCodeGoto (tree->falseLabel);
2838 if (tree->trueLabel)
2840 ic = newiCodeCondition (condition,
2845 if (tree->falseLabel)
2846 geniCodeGoto (tree->falseLabel);
2850 ic = newiCodeCondition (condition,
2857 ast2iCode (tree->right,lvl+1);
2860 /*-----------------------------------------------------------------*/
2861 /* geniCodeJumpTable - tries to create a jump table for switch */
2862 /*-----------------------------------------------------------------*/
2864 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2866 int min = 0, max = 0, t, cnt = 0;
2873 if (!tree || !caseVals)
2876 /* the criteria for creating a jump table is */
2877 /* all integer numbers between the maximum & minimum must */
2878 /* be present , the maximum value should not exceed 255 */
2879 min = max = (int) floatFromVal (vch = caseVals);
2880 sprintf (buffer, "_case_%d_%d",
2881 tree->values.switchVals.swNum,
2883 addSet (&labels, newiTempLabel (buffer));
2885 /* if there is only one case value then no need */
2886 if (!(vch = vch->next))
2891 if (((t = (int) floatFromVal (vch)) - max) != 1)
2893 sprintf (buffer, "_case_%d_%d",
2894 tree->values.switchVals.swNum,
2896 addSet (&labels, newiTempLabel (buffer));
2902 /* if the number of case statements <= 2 then */
2903 /* it is not economical to create the jump table */
2904 /* since two compares are needed for boundary conditions */
2905 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2908 if (tree->values.switchVals.swDefault)
2909 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2911 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2913 falseLabel = newiTempLabel (buffer);
2915 /* so we can create a jumptable */
2916 /* first we rule out the boundary conditions */
2917 /* if only optimization says so */
2918 if (!optimize.noJTabBoundary)
2920 sym_link *cetype = getSpec (operandType (cond));
2921 /* no need to check the lower bound if
2922 the condition is unsigned & minimum value is zero */
2923 if (!(min == 0 && SPEC_USIGN (cetype)))
2925 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2926 ic = newiCodeCondition (boundary, falseLabel, NULL);
2930 /* now for upper bounds */
2931 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
2932 ic = newiCodeCondition (boundary, falseLabel, NULL);
2936 /* if the min is not zero then we no make it zero */
2939 cond = geniCodeSubtract (cond, operandFromLit (min));
2940 setOperandType (cond, UCHARTYPE);
2943 /* now create the jumptable */
2944 ic = newiCode (JUMPTABLE, NULL, NULL);
2945 IC_JTCOND (ic) = cond;
2946 IC_JTLABELS (ic) = labels;
2951 /*-----------------------------------------------------------------*/
2952 /* geniCodeSwitch - changes a switch to a if statement */
2953 /*-----------------------------------------------------------------*/
2955 geniCodeSwitch (ast * tree,int lvl)
2958 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
2959 value *caseVals = tree->values.switchVals.swVals;
2960 symbol *trueLabel, *falseLabel;
2962 /* if we can make this a jump table */
2963 if (geniCodeJumpTable (cond, caseVals, tree))
2964 goto jumpTable; /* no need for the comparison */
2966 /* for the cases defined do */
2970 operand *compare = geniCodeLogic (cond,
2971 operandFromValue (caseVals),
2974 sprintf (buffer, "_case_%d_%d",
2975 tree->values.switchVals.swNum,
2976 (int) floatFromVal (caseVals));
2977 trueLabel = newiTempLabel (buffer);
2979 ic = newiCodeCondition (compare, trueLabel, NULL);
2981 caseVals = caseVals->next;
2986 /* if default is present then goto break else break */
2987 if (tree->values.switchVals.swDefault)
2988 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2990 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2992 falseLabel = newiTempLabel (buffer);
2993 geniCodeGoto (falseLabel);
2996 ast2iCode (tree->right,lvl+1);
2999 /*-----------------------------------------------------------------*/
3000 /* geniCodeInline - intermediate code for inline assembler */
3001 /*-----------------------------------------------------------------*/
3003 geniCodeInline (ast * tree)
3007 ic = newiCode (INLINEASM, NULL, NULL);
3008 IC_INLINE (ic) = tree->values.inlineasm;
3012 /*-----------------------------------------------------------------*/
3013 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3014 /* particular case. Ie : assigning or dereferencing array or ptr */
3015 /*-----------------------------------------------------------------*/
3016 set * lvaluereqSet = NULL;
3017 typedef struct lvalItem
3024 /*-----------------------------------------------------------------*/
3025 /* addLvaluereq - add a flag for lvalreq for current ast level */
3026 /*-----------------------------------------------------------------*/
3027 void addLvaluereq(int lvl)
3029 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3032 addSetHead(&lvaluereqSet,lpItem);
3035 /*-----------------------------------------------------------------*/
3036 /* delLvaluereq - del a flag for lvalreq for current ast level */
3037 /*-----------------------------------------------------------------*/
3041 lpItem = getSet(&lvaluereqSet);
3042 if(lpItem) free(lpItem);
3044 /*-----------------------------------------------------------------*/
3045 /* clearLvaluereq - clear lvalreq flag */
3046 /*-----------------------------------------------------------------*/
3047 void clearLvaluereq()
3050 lpItem = peekSet(lvaluereqSet);
3051 if(lpItem) lpItem->req = 0;
3053 /*-----------------------------------------------------------------*/
3054 /* getLvaluereq - get the last lvalreq level */
3055 /*-----------------------------------------------------------------*/
3056 int getLvaluereqLvl()
3059 lpItem = peekSet(lvaluereqSet);
3060 if(lpItem) return lpItem->lvl;
3063 /*-----------------------------------------------------------------*/
3064 /* isLvaluereq - is lvalreq valid for this level ? */
3065 /*-----------------------------------------------------------------*/
3066 int isLvaluereq(int lvl)
3069 lpItem = peekSet(lvaluereqSet);
3070 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3074 /*-----------------------------------------------------------------*/
3075 /* ast2iCode - creates an icodeList from an ast */
3076 /*-----------------------------------------------------------------*/
3078 ast2iCode (ast * tree,int lvl)
3080 operand *left = NULL;
3081 operand *right = NULL;
3084 /* set the global variables for filename & line number */
3086 filename = tree->filename;
3088 lineno = tree->lineno;
3090 block = tree->block;
3092 scopeLevel = tree->level;
3094 if (tree->type == EX_VALUE)
3095 return operandFromValue (tree->opval.val);
3097 if (tree->type == EX_LINK)
3098 return operandFromLink (tree->opval.lnk);
3100 /* if we find a nullop */
3101 if (tree->type == EX_OP &&
3102 (tree->opval.op == NULLOP ||
3103 tree->opval.op == BLOCK))
3105 ast2iCode (tree->left,lvl+1);
3106 ast2iCode (tree->right,lvl+1);
3110 /* special cases for not evaluating */
3111 if (tree->opval.op != ':' &&
3112 tree->opval.op != '?' &&
3113 tree->opval.op != CALL &&
3114 tree->opval.op != IFX &&
3115 tree->opval.op != LABEL &&
3116 tree->opval.op != GOTO &&
3117 tree->opval.op != SWITCH &&
3118 tree->opval.op != FUNCTION &&
3119 tree->opval.op != INLINEASM)
3122 if (IS_ASSIGN_OP (tree->opval.op) ||
3123 IS_DEREF_OP (tree) ||
3124 (tree->opval.op == '&' && !tree->right) ||
3125 tree->opval.op == PTR_OP)
3128 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3129 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3132 left = operandFromAst (tree->left,lvl);
3134 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3135 left = geniCodeRValue (left, TRUE);
3139 left = operandFromAst (tree->left,lvl);
3141 if (tree->opval.op == INC_OP ||
3142 tree->opval.op == DEC_OP)
3145 right = operandFromAst (tree->right,lvl);
3150 right = operandFromAst (tree->right,lvl);
3154 /* now depending on the type of operand */
3155 /* this will be a biggy */
3156 switch (tree->opval.op)
3159 case '[': /* array operation */
3161 sym_link *ltype = operandType (left);
3162 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3163 right = geniCodeRValue (right, TRUE);
3166 return geniCodeArray (left, right,lvl);
3168 case '.': /* structure dereference */
3169 if (IS_PTR (operandType (left)))
3170 left = geniCodeRValue (left, TRUE);
3172 left = geniCodeRValue (left, FALSE);
3174 return geniCodeStruct (left, right, tree->lvalue);
3176 case PTR_OP: /* structure pointer dereference */
3179 pType = operandType (left);
3180 left = geniCodeRValue (left, TRUE);
3182 setOClass (pType, getSpec (operandType (left)));
3185 return geniCodeStruct (left, right, tree->lvalue);
3187 case INC_OP: /* increment operator */
3189 return geniCodePostInc (left);
3191 return geniCodePreInc (right);
3193 case DEC_OP: /* decrement operator */
3195 return geniCodePostDec (left);
3197 return geniCodePreDec (right);
3199 case '&': /* bitwise and or address of operator */
3201 { /* this is a bitwise operator */
3202 left = geniCodeRValue (left, FALSE);
3203 right = geniCodeRValue (right, FALSE);
3204 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3207 return geniCodeAddressOf (left);
3209 case '|': /* bitwise or & xor */
3211 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3212 geniCodeRValue (right, FALSE),
3217 return geniCodeDivision (geniCodeRValue (left, FALSE),
3218 geniCodeRValue (right, FALSE));
3221 return geniCodeModulus (geniCodeRValue (left, FALSE),
3222 geniCodeRValue (right, FALSE));
3225 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3226 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3228 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3232 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3233 geniCodeRValue (right, FALSE));
3235 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3239 return geniCodeAdd (geniCodeRValue (left, FALSE),
3240 geniCodeRValue (right, FALSE),lvl);
3242 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3245 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3246 geniCodeRValue (right, FALSE));
3249 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3250 geniCodeRValue (right, FALSE));
3252 return geniCodeCast (operandType (left),
3253 geniCodeRValue (right, FALSE), FALSE);
3259 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3263 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3264 setOperandType (op, UCHARTYPE);
3275 return geniCodeLogic (geniCodeRValue (left, FALSE),
3276 geniCodeRValue (right, FALSE),
3279 return geniCodeConditional (tree,lvl);
3282 return operandFromLit (getSize (tree->right->ftype));
3286 sym_link *rtype = operandType (right);
3287 sym_link *ltype = operandType (left);
3288 if (IS_PTR (rtype) && IS_ITEMP (right)
3289 && right->isaddr && compareType (rtype->next, ltype) == 1)
3290 right = geniCodeRValue (right, TRUE);
3292 right = geniCodeRValue (right, FALSE);
3294 geniCodeAssign (left, right, 0);
3299 geniCodeAssign (left,
3300 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3302 geniCodeRValue (right, FALSE),FALSE), 0);
3306 geniCodeAssign (left,
3307 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3309 geniCodeRValue (right, FALSE)), 0);
3312 geniCodeAssign (left,
3313 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3315 geniCodeRValue (right, FALSE)), 0);
3318 sym_link *rtype = operandType (right);
3319 sym_link *ltype = operandType (left);
3320 if (IS_PTR (rtype) && IS_ITEMP (right)
3321 && right->isaddr && compareType (rtype->next, ltype) == 1)
3322 right = geniCodeRValue (right, TRUE);
3324 right = geniCodeRValue (right, FALSE);
3327 return geniCodeAssign (left,
3328 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3334 sym_link *rtype = operandType (right);
3335 sym_link *ltype = operandType (left);
3336 if (IS_PTR (rtype) && IS_ITEMP (right)
3337 && right->isaddr && compareType (rtype->next, ltype) == 1)
3339 right = geniCodeRValue (right, TRUE);
3343 right = geniCodeRValue (right, FALSE);
3346 geniCodeAssign (left,
3347 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3353 geniCodeAssign (left,
3354 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3356 geniCodeRValue (right, FALSE)), 0);
3359 geniCodeAssign (left,
3360 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3362 geniCodeRValue (right, FALSE)), 0);
3365 geniCodeAssign (left,
3366 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3368 geniCodeRValue (right, FALSE),
3370 operandType (left)), 0);
3373 geniCodeAssign (left,
3374 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3376 geniCodeRValue (right, FALSE),
3378 operandType (left)), 0);
3381 geniCodeAssign (left,
3382 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3384 geniCodeRValue (right, FALSE),
3386 operandType (left)), 0);
3388 return geniCodeRValue (right, FALSE);
3391 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3394 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3395 return ast2iCode (tree->right,lvl+1);
3398 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3399 return ast2iCode (tree->right,lvl+1);
3402 geniCodeFunctionBody (tree,lvl);
3406 geniCodeReturn (right);
3410 geniCodeIfx (tree,lvl);
3414 geniCodeSwitch (tree,lvl);
3418 geniCodeInline (tree);
3425 /*-----------------------------------------------------------------*/
3426 /* reverseICChain - gets from the list and creates a linkedlist */
3427 /*-----------------------------------------------------------------*/
3434 while ((loop = getSet (&iCodeChain)))
3446 /*-----------------------------------------------------------------*/
3447 /* iCodeFromAst - given an ast will convert it to iCode */
3448 /*-----------------------------------------------------------------*/
3450 iCodeFromAst (ast * tree)
3452 returnLabel = newiTempLabel ("_return");
3453 entryLabel = newiTempLabel ("_entry");
3455 return reverseiCChain ();