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);
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);
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 (checkType (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 (checkType (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 werror (E_CONTINUE, "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;
1626 SPEC_SHORT(getSpec(resType))=0;
1629 /* if the right is a literal & power of 2 */
1630 /* then make it a left shift */
1631 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1632 efficient in most cases than 2 bytes result = 2 bytes << literal
1633 if port has 1 byte muldiv */
1634 if (p2 && !IS_FLOAT (letype) &&
1635 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1636 (port->muldiv.native_below == 1)))
1638 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1640 /* LEFT_OP need same size for left and result, */
1641 left = geniCodeCast (resType, left, TRUE);
1642 ltype = operandType (left);
1644 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1648 ic = newiCode ('*', left, right); /* normal multiplication */
1649 /* if the size left or right > 1 then support routine */
1650 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1654 IC_RESULT (ic) = newiTempOperand (resType, 1);
1657 return IC_RESULT (ic);
1660 /*-----------------------------------------------------------------*/
1661 /* geniCodeDivision - gen intermediate code for division */
1662 /*-----------------------------------------------------------------*/
1664 geniCodeDivision (operand * left, operand * right)
1669 sym_link *rtype = operandType (right);
1670 sym_link *retype = getSpec (rtype);
1671 sym_link *ltype = operandType (left);
1672 sym_link *letype = getSpec (ltype);
1674 resType = usualBinaryConversions (&left, &right);
1676 /* if the right is a literal & power of 2 */
1677 /* then make it a right shift */
1678 if (IS_LITERAL (retype) &&
1679 !IS_FLOAT (letype) &&
1680 (p2 = powof2 ((unsigned long)
1681 floatFromVal (right->operand.valOperand)))) {
1682 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1686 ic = newiCode ('/', left, right); /* normal division */
1687 /* if the size left or right > 1 then support routine */
1688 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1691 IC_RESULT (ic) = newiTempOperand (resType, 0);
1694 return IC_RESULT (ic);
1696 /*-----------------------------------------------------------------*/
1697 /* geniCodeModulus - gen intermediate code for modulus */
1698 /*-----------------------------------------------------------------*/
1700 geniCodeModulus (operand * left, operand * right)
1706 /* if they are both literal then we know the result */
1707 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1708 return operandFromValue (valMod (left->operand.valOperand,
1709 right->operand.valOperand));
1711 resType = usualBinaryConversions (&left, &right);
1713 /* now they are the same size */
1714 ic = newiCode ('%', left, right);
1716 /* if the size left or right > 1 then support routine */
1717 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1719 IC_RESULT (ic) = newiTempOperand (resType, 0);
1722 return IC_RESULT (ic);
1725 /*-----------------------------------------------------------------*/
1726 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1727 /*-----------------------------------------------------------------*/
1729 geniCodePtrPtrSubtract (operand * left, operand * right)
1735 /* if they are both literals then */
1736 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1738 result = operandFromValue (valMinus (left->operand.valOperand,
1739 right->operand.valOperand));
1743 ic = newiCode ('-', left, right);
1745 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1749 return geniCodeDivision (result,
1750 operandFromLit (getSize (ltype->next)));
1753 /*-----------------------------------------------------------------*/
1754 /* geniCodeSubtract - generates code for subtraction */
1755 /*-----------------------------------------------------------------*/
1757 geniCodeSubtract (operand * left, operand * right)
1764 /* if they both pointers then */
1765 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1766 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1767 return geniCodePtrPtrSubtract (left, right);
1769 /* if they are both literal then we know the result */
1770 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1771 && left->isLiteral && right->isLiteral)
1772 return operandFromValue (valMinus (left->operand.valOperand,
1773 right->operand.valOperand));
1775 /* if left is an array or pointer */
1776 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1778 isarray = left->isaddr;
1779 right = geniCodeMultiply (right,
1780 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1781 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1784 { /* make them the same size */
1785 resType = usualBinaryConversions (&left, &right);
1788 ic = newiCode ('-', left, right);
1790 IC_RESULT (ic) = newiTempOperand (resType, 1);
1791 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1793 /* if left or right is a float */
1794 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1798 return IC_RESULT (ic);
1801 /*-----------------------------------------------------------------*/
1802 /* geniCodeAdd - generates iCode for addition */
1803 /*-----------------------------------------------------------------*/
1805 geniCodeAdd (operand * left, operand * right,int lvl)
1813 /* if left is an array then array access */
1814 if (IS_ARRAY (ltype))
1815 return geniCodeArray (left, right,lvl);
1817 /* if the right side is LITERAL zero */
1818 /* return the left side */
1819 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1822 /* if left is literal zero return right */
1823 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1826 /* if left is an array or pointer then size */
1829 isarray = left->isaddr;
1830 // there is no need to multiply with 1
1831 if (getSize(ltype->next)!=1) {
1832 size = operandFromLit (getSize (ltype->next));
1833 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1835 resType = copyLinkChain (ltype);
1838 { /* make them the same size */
1839 resType = usualBinaryConversions (&left, &right);
1842 /* if they are both literals then we know */
1843 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1844 && left->isLiteral && right->isLiteral)
1845 return operandFromValue (valPlus (valFromType (letype),
1846 valFromType (retype)));
1848 ic = newiCode ('+', left, right);
1850 IC_RESULT (ic) = newiTempOperand (resType, 1);
1851 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1853 /* if left or right is a float then support
1855 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1860 return IC_RESULT (ic);
1864 /*-----------------------------------------------------------------*/
1865 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1866 /*-----------------------------------------------------------------*/
1868 aggrToPtr (sym_link * type, bool force)
1874 if (IS_PTR (type) && !force)
1877 etype = getSpec (type);
1881 /* if the output class is generic */
1882 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1883 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1885 /* if the variable was declared a constant */
1886 /* then the pointer points to a constant */
1887 if (IS_CONSTANT (etype))
1888 DCL_PTR_CONST (ptype) = 1;
1890 /* the variable was volatile then pointer to volatile */
1891 if (IS_VOLATILE (etype))
1892 DCL_PTR_VOLATILE (ptype) = 1;
1896 /*-----------------------------------------------------------------*/
1897 /* geniCodeArray2Ptr - array to pointer */
1898 /*-----------------------------------------------------------------*/
1900 geniCodeArray2Ptr (operand * op)
1902 sym_link *optype = operandType (op);
1903 sym_link *opetype = getSpec (optype);
1905 /* set the pointer depending on the storage class */
1906 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1907 DCL_PTR_CONST (optype) = port->mem.code_ro;
1910 /* if the variable was declared a constant */
1911 /* then the pointer points to a constant */
1912 if (IS_CONSTANT (opetype))
1913 DCL_PTR_CONST (optype) = 1;
1915 /* the variable was volatile then pointer to volatile */
1916 if (IS_VOLATILE (opetype))
1917 DCL_PTR_VOLATILE (optype) = 1;
1923 /*-----------------------------------------------------------------*/
1924 /* geniCodeArray - array access */
1925 /*-----------------------------------------------------------------*/
1927 geniCodeArray (operand * left, operand * right,int lvl)
1930 sym_link *ltype = operandType (left);
1934 if (IS_PTR (ltype->next) && left->isaddr)
1936 left = geniCodeRValue (left, FALSE);
1938 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
1941 right = geniCodeMultiply (right,
1942 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1944 /* we can check for limits here */
1945 if (isOperandLiteral (right) &&
1948 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
1950 werror (E_ARRAY_BOUND);
1951 right = operandFromLit (0);
1954 ic = newiCode ('+', left, right);
1956 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
1957 !IS_AGGREGATE (ltype->next) &&
1958 !IS_PTR (ltype->next))
1959 ? ltype : ltype->next), 0);
1961 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
1963 return IC_RESULT (ic);
1966 /*-----------------------------------------------------------------*/
1967 /* geniCodeStruct - generates intermediate code for structres */
1968 /*-----------------------------------------------------------------*/
1970 geniCodeStruct (operand * left, operand * right, bool islval)
1973 sym_link *type = operandType (left);
1974 sym_link *etype = getSpec (type);
1976 symbol *element = getStructElement (SPEC_STRUCT (etype),
1977 right->operand.symOperand);
1979 /* add the offset */
1980 ic = newiCode ('+', left, operandFromLit (element->offset));
1982 IC_RESULT (ic) = newiTempOperand (element->type, 0);
1984 /* preserve the storage & output class of the struct */
1985 /* as well as the volatile attribute */
1986 retype = getSpec (operandType (IC_RESULT (ic)));
1987 SPEC_SCLS (retype) = SPEC_SCLS (etype);
1988 SPEC_OCLS (retype) = SPEC_OCLS (etype);
1989 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
1991 if (IS_PTR (element->type))
1992 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
1994 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
1998 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2001 /*-----------------------------------------------------------------*/
2002 /* geniCodePostInc - generate int code for Post increment */
2003 /*-----------------------------------------------------------------*/
2005 geniCodePostInc (operand * op)
2009 sym_link *optype = operandType (op);
2011 operand *rv = (IS_ITEMP (op) ?
2012 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2014 sym_link *rvtype = operandType (rv);
2017 /* if this is not an address we have trouble */
2020 werror (E_LVALUE_REQUIRED, "++");
2024 rOp = newiTempOperand (rvtype, 0);
2030 geniCodeAssign (rOp, rv, 0);
2032 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2033 if (IS_FLOAT (rvtype))
2034 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2036 ic = newiCode ('+', rv, operandFromLit (size));
2038 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2041 geniCodeAssign (op, result, 0);
2047 /*-----------------------------------------------------------------*/
2048 /* geniCodePreInc - generate code for preIncrement */
2049 /*-----------------------------------------------------------------*/
2051 geniCodePreInc (operand * op)
2054 sym_link *optype = operandType (op);
2055 operand *rop = (IS_ITEMP (op) ?
2056 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2058 sym_link *roptype = operandType (rop);
2064 werror (E_LVALUE_REQUIRED, "++");
2069 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2070 if (IS_FLOAT (roptype))
2071 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2073 ic = newiCode ('+', rop, operandFromLit (size));
2074 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2078 return geniCodeAssign (op, result, 0);
2081 /*-----------------------------------------------------------------*/
2082 /* geniCodePostDec - generates code for Post decrement */
2083 /*-----------------------------------------------------------------*/
2085 geniCodePostDec (operand * op)
2089 sym_link *optype = operandType (op);
2091 operand *rv = (IS_ITEMP (op) ?
2092 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2094 sym_link *rvtype = operandType (rv);
2097 /* if this is not an address we have trouble */
2100 werror (E_LVALUE_REQUIRED, "++");
2104 rOp = newiTempOperand (rvtype, 0);
2110 geniCodeAssign (rOp, rv, 0);
2112 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2113 if (IS_FLOAT (rvtype))
2114 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2116 ic = newiCode ('-', rv, operandFromLit (size));
2118 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2121 geniCodeAssign (op, result, 0);
2127 /*-----------------------------------------------------------------*/
2128 /* geniCodePreDec - generate code for pre decrement */
2129 /*-----------------------------------------------------------------*/
2131 geniCodePreDec (operand * op)
2134 sym_link *optype = operandType (op);
2135 operand *rop = (IS_ITEMP (op) ?
2136 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2138 sym_link *roptype = operandType (rop);
2144 werror (E_LVALUE_REQUIRED, "++");
2149 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2150 if (IS_FLOAT (roptype))
2151 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2153 ic = newiCode ('-', rop, operandFromLit (size));
2154 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2158 return geniCodeAssign (op, result, 0);
2162 /*-----------------------------------------------------------------*/
2163 /* geniCodeBitwise - gen int code for bitWise operators */
2164 /*-----------------------------------------------------------------*/
2166 geniCodeBitwise (operand * left, operand * right,
2167 int oper, sym_link * resType)
2171 left = geniCodeCast (resType, left, TRUE);
2172 right = geniCodeCast (resType, right, TRUE);
2174 ic = newiCode (oper, left, right);
2175 IC_RESULT (ic) = newiTempOperand (resType, 0);
2178 return IC_RESULT (ic);
2181 /*-----------------------------------------------------------------*/
2182 /* geniCodeAddressOf - gens icode for '&' address of operator */
2183 /*-----------------------------------------------------------------*/
2185 geniCodeAddressOf (operand * op)
2189 sym_link *optype = operandType (op);
2190 sym_link *opetype = getSpec (optype);
2192 /* lvalue check already done in decorateType */
2193 /* this must be a lvalue */
2194 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2195 /* werror (E_LVALUE_REQUIRED,"&"); */
2200 p->class = DECLARATOR;
2202 /* set the pointer depending on the storage class */
2203 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2204 DCL_PTR_CONST (p) = port->mem.code_ro;
2206 /* make sure we preserve the const & volatile */
2207 if (IS_CONSTANT (opetype))
2208 DCL_PTR_CONST (p) = 1;
2210 if (IS_VOLATILE (opetype))
2211 DCL_PTR_VOLATILE (p) = 1;
2213 p->next = copyLinkChain (optype);
2215 /* if already a temp */
2218 setOperandType (op, p);
2223 /* other wise make this of the type coming in */
2224 ic = newiCode (ADDRESS_OF, op, NULL);
2225 IC_RESULT (ic) = newiTempOperand (p, 1);
2226 IC_RESULT (ic)->isaddr = 0;
2228 return IC_RESULT (ic);
2230 /*-----------------------------------------------------------------*/
2231 /* setOClass - sets the output class depending on the pointer type */
2232 /*-----------------------------------------------------------------*/
2234 setOClass (sym_link * ptr, sym_link * spec)
2236 switch (DCL_TYPE (ptr))
2239 SPEC_OCLS (spec) = data;
2243 SPEC_OCLS (spec) = generic;
2247 SPEC_OCLS (spec) = xdata;
2251 SPEC_OCLS (spec) = code;
2255 SPEC_OCLS (spec) = idata;
2259 SPEC_OCLS (spec) = xstack;
2263 SPEC_OCLS (spec) = eeprom;
2272 /*-----------------------------------------------------------------*/
2273 /* geniCodeDerefPtr - dereference pointer with '*' */
2274 /*-----------------------------------------------------------------*/
2276 geniCodeDerefPtr (operand * op,int lvl)
2278 sym_link *rtype, *retype;
2279 sym_link *optype = operandType (op);
2281 /* if this is a pointer then generate the rvalue */
2282 if (IS_PTR (optype))
2284 if (IS_TRUE_SYMOP (op))
2287 op = geniCodeRValue (op, TRUE);
2290 op = geniCodeRValue (op, TRUE);
2293 /* now get rid of the pointer part */
2294 if (isLvaluereq(lvl) && IS_ITEMP (op))
2296 retype = getSpec (rtype = copyLinkChain (optype));
2300 retype = getSpec (rtype = copyLinkChain (optype->next));
2303 /* if this is a pointer then outputclass needs 2b updated */
2304 if (IS_PTR (optype))
2305 setOClass (optype, retype);
2307 op->isGptr = IS_GENPTR (optype);
2309 /* if the pointer was declared as a constant */
2310 /* then we cannot allow assignment to the derefed */
2311 if (IS_PTR_CONST (optype))
2312 SPEC_CONST (retype) = 1;
2314 op->isaddr = (IS_PTR (rtype) ||
2315 IS_STRUCT (rtype) ||
2320 if (!isLvaluereq(lvl))
2321 op = geniCodeRValue (op, TRUE);
2323 setOperandType (op, rtype);
2328 /*-----------------------------------------------------------------*/
2329 /* geniCodeUnaryMinus - does a unary minus of the operand */
2330 /*-----------------------------------------------------------------*/
2332 geniCodeUnaryMinus (operand * op)
2335 sym_link *optype = operandType (op);
2337 if (IS_LITERAL (optype))
2338 return operandFromLit (-floatFromVal (op->operand.valOperand));
2340 ic = newiCode (UNARYMINUS, op, NULL);
2341 IC_RESULT (ic) = newiTempOperand (optype, 0);
2343 return IC_RESULT (ic);
2346 /*-----------------------------------------------------------------*/
2347 /* geniCodeLeftShift - gen i code for left shift */
2348 /*-----------------------------------------------------------------*/
2350 geniCodeLeftShift (operand * left, operand * right)
2354 ic = newiCode (LEFT_OP, left, right);
2355 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2357 return IC_RESULT (ic);
2360 /*-----------------------------------------------------------------*/
2361 /* geniCodeRightShift - gen i code for right shift */
2362 /*-----------------------------------------------------------------*/
2364 geniCodeRightShift (operand * left, operand * right)
2368 ic = newiCode (RIGHT_OP, left, right);
2369 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2371 return IC_RESULT (ic);
2374 #if defined(__BORLANDC__) || defined(_MSC_VER)
2375 #define LONG_LONG __int64
2377 #define LONG_LONG long long
2380 /*-----------------------------------------------------------------*/
2381 /* geniCodeLogic- logic code */
2382 /*-----------------------------------------------------------------*/
2384 geniCodeLogic (operand * left, operand * right, int op)
2388 sym_link *rtype = operandType (right);
2389 sym_link *ltype = operandType (left);
2391 /* left is integral type and right is literal then
2392 check if the literal value is within bounds */
2393 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2395 int nbits = bitsForType (ltype);
2396 long v = (long) operandLitValue (right);
2398 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2399 werror (W_CONST_RANGE, " compare operation ");
2402 ctype = usualBinaryConversions (&left, &right);
2404 ic = newiCode (op, left, right);
2405 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2407 /* if comparing float
2408 and not a '==' || '!=' || '&&' || '||' (these
2410 if (IS_FLOAT(ctype) &&
2418 return IC_RESULT (ic);
2421 /*-----------------------------------------------------------------*/
2422 /* geniCodeUnary - for a a generic unary operation */
2423 /*-----------------------------------------------------------------*/
2425 geniCodeUnary (operand * op, int oper)
2427 iCode *ic = newiCode (oper, op, NULL);
2429 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2431 return IC_RESULT (ic);
2434 /*-----------------------------------------------------------------*/
2435 /* geniCodeConditional - geniCode for '?' ':' operation */
2436 /*-----------------------------------------------------------------*/
2438 geniCodeConditional (ast * tree,int lvl)
2441 symbol *falseLabel = newiTempLabel (NULL);
2442 symbol *exitLabel = newiTempLabel (NULL);
2443 operand *cond = ast2iCode (tree->left,lvl+1);
2444 operand *true, *false, *result;
2446 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2450 true = ast2iCode (tree->right->left,lvl+1);
2452 /* move the value to a new Operand */
2453 result = newiTempOperand (operandType (true), 0);
2454 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2456 /* generate an unconditional goto */
2457 geniCodeGoto (exitLabel);
2459 /* now for the right side */
2460 geniCodeLabel (falseLabel);
2462 false = ast2iCode (tree->right->right,lvl+1);
2463 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2465 /* create the exit label */
2466 geniCodeLabel (exitLabel);
2471 /*-----------------------------------------------------------------*/
2472 /* geniCodeAssign - generate code for assignment */
2473 /*-----------------------------------------------------------------*/
2475 geniCodeAssign (operand * left, operand * right, int nosupdate)
2478 sym_link *ltype = operandType (left);
2479 sym_link *rtype = operandType (right);
2481 if (!left->isaddr && !IS_ITEMP (left))
2483 werror (E_LVALUE_REQUIRED, "assignment");
2487 /* left is integral type and right is literal then
2488 check if the literal value is within bounds */
2489 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2491 int nbits = bitsForType (ltype);
2492 long v = (long) operandLitValue (right);
2494 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2495 werror (W_CONST_RANGE, " = operation");
2498 /* if the left & right type don't exactly match */
2499 /* if pointer set then make sure the check is
2500 done with the type & not the pointer */
2501 /* then cast rights type to left */
2503 /* first check the type for pointer assignement */
2504 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2505 checkType (ltype, rtype) < 0)
2507 if (checkType (ltype->next, rtype) < 0)
2508 right = geniCodeCast (ltype->next, right, TRUE);
2510 else if (checkType (ltype, rtype) < 0)
2511 right = geniCodeCast (ltype, right, TRUE);
2513 /* if left is a true symbol & ! volatile
2514 create an assignment to temporary for
2515 the right & then assign this temporary
2516 to the symbol this is SSA . isn't it simple
2517 and folks have published mountains of paper on it */
2518 if (IS_TRUE_SYMOP (left) &&
2519 !isOperandVolatile (left, FALSE) &&
2520 isOperandGlobal (left))
2524 if (IS_TRUE_SYMOP (right))
2525 sym = OP_SYMBOL (right);
2526 ic = newiCode ('=', NULL, right);
2527 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2528 SPIL_LOC (right) = sym;
2532 ic = newiCode ('=', NULL, right);
2533 IC_RESULT (ic) = left;
2536 /* if left isgptr flag is set then support
2537 routine will be required */
2541 ic->nosupdate = nosupdate;
2545 /*-----------------------------------------------------------------*/
2546 /* geniCodeSEParms - generate code for side effecting fcalls */
2547 /*-----------------------------------------------------------------*/
2549 geniCodeSEParms (ast * parms,int lvl)
2554 if (parms->type == EX_OP && parms->opval.op == PARAM)
2556 geniCodeSEParms (parms->left,lvl);
2557 geniCodeSEParms (parms->right,lvl);
2561 /* hack don't like this but too lazy to think of
2563 if (IS_ADDRESS_OF_OP (parms))
2564 parms->left->lvalue = 1;
2566 if (IS_CAST_OP (parms) &&
2567 IS_PTR (parms->ftype) &&
2568 IS_ADDRESS_OF_OP (parms->right))
2569 parms->right->left->lvalue = 1;
2571 parms->opval.oprnd =
2572 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2574 parms->type = EX_OPERAND;
2577 /*-----------------------------------------------------------------*/
2578 /* geniCodeParms - generates parameters */
2579 /*-----------------------------------------------------------------*/
2581 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2589 /* if this is a param node then do the left & right */
2590 if (parms->type == EX_OP && parms->opval.op == PARAM)
2592 geniCodeParms (parms->left, stack, fetype, func,lvl);
2593 geniCodeParms (parms->right, stack, fetype, func,lvl);
2597 /* get the parameter value */
2598 if (parms->type == EX_OPERAND)
2599 pval = parms->opval.oprnd;
2602 /* maybe this else should go away ?? */
2603 /* hack don't like this but too lazy to think of
2605 if (IS_ADDRESS_OF_OP (parms))
2606 parms->left->lvalue = 1;
2608 if (IS_CAST_OP (parms) &&
2609 IS_PTR (parms->ftype) &&
2610 IS_ADDRESS_OF_OP (parms->right))
2611 parms->right->left->lvalue = 1;
2613 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2616 /* if register parm then make it a send */
2617 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2618 IS_REGPARM (parms->etype)) && !func->hasVargs)
2620 ic = newiCode (SEND, pval, NULL);
2625 /* now decide whether to push or assign */
2626 if (!(options.stackAuto || IS_RENT (fetype)))
2630 operand *top = operandFromSymbol (parms->argSym);
2631 geniCodeAssign (top, pval, 1);
2635 sym_link *p = operandType (pval);
2637 ic = newiCode (IPUSH, pval, NULL);
2639 /* update the stack adjustment */
2640 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2647 /*-----------------------------------------------------------------*/
2648 /* geniCodeCall - generates temp code for calling */
2649 /*-----------------------------------------------------------------*/
2651 geniCodeCall (operand * left, ast * parms,int lvl)
2655 sym_link *type, *etype;
2658 /* take care of parameters with side-effecting
2659 function calls in them, this is required to take care
2660 of overlaying function parameters */
2661 geniCodeSEParms (parms,lvl);
2663 /* first the parameters */
2664 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2666 /* now call : if symbol then pcall */
2667 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2668 ic = newiCode (PCALL, left, NULL);
2670 ic = newiCode (CALL, left, NULL);
2672 IC_ARGS (ic) = left->operand.symOperand->args;
2673 type = copyLinkChain (operandType (left)->next);
2674 etype = getSpec (type);
2675 SPEC_EXTR (etype) = 0;
2676 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2680 /* stack adjustment after call */
2681 ic->parmBytes = stack;
2686 /*-----------------------------------------------------------------*/
2687 /* geniCodeReceive - generate intermediate code for "receive" */
2688 /*-----------------------------------------------------------------*/
2690 geniCodeReceive (value * args)
2692 /* for all arguments that are passed in registers */
2696 if (IS_REGPARM (args->etype))
2698 operand *opr = operandFromValue (args);
2700 symbol *sym = OP_SYMBOL (opr);
2703 /* we will use it after all optimizations
2704 and before liveRange calculation */
2705 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2708 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2709 options.stackAuto == 0 &&
2715 opl = newiTempOperand (args->type, 0);
2717 sym->reqv->key = sym->key;
2718 OP_SYMBOL (sym->reqv)->key = sym->key;
2719 OP_SYMBOL (sym->reqv)->isreqv = 1;
2720 OP_SYMBOL (sym->reqv)->islocal = 0;
2721 SPIL_LOC (sym->reqv) = sym;
2725 ic = newiCode (RECEIVE, NULL, NULL);
2726 currFunc->recvSize = getSize (sym->etype);
2727 IC_RESULT (ic) = opr;
2735 /*-----------------------------------------------------------------*/
2736 /* geniCodeFunctionBody - create the function body */
2737 /*-----------------------------------------------------------------*/
2739 geniCodeFunctionBody (ast * tree,int lvl)
2746 /* reset the auto generation */
2752 func = ast2iCode (tree->left,lvl+1);
2753 fetype = getSpec (operandType (func));
2755 savelineno = lineno;
2756 lineno = OP_SYMBOL (func)->lineDef;
2757 /* create an entry label */
2758 geniCodeLabel (entryLabel);
2759 lineno = savelineno;
2761 /* create a proc icode */
2762 ic = newiCode (FUNCTION, func, NULL);
2763 /* if the function has parmas then */
2764 /* save the parameters information */
2765 ic->argLabel.args = tree->values.args;
2766 ic->lineno = OP_SYMBOL (func)->lineDef;
2770 /* for all parameters that are passed
2771 on registers add a "receive" */
2772 geniCodeReceive (tree->values.args);
2774 /* generate code for the body */
2775 ast2iCode (tree->right,lvl+1);
2777 /* create a label for return */
2778 geniCodeLabel (returnLabel);
2780 /* now generate the end proc */
2781 ic = newiCode (ENDFUNCTION, func, NULL);
2786 /*-----------------------------------------------------------------*/
2787 /* geniCodeReturn - gen icode for 'return' statement */
2788 /*-----------------------------------------------------------------*/
2790 geniCodeReturn (operand * op)
2794 /* if the operand is present force an rvalue */
2796 op = geniCodeRValue (op, FALSE);
2798 ic = newiCode (RETURN, op, NULL);
2802 /*-----------------------------------------------------------------*/
2803 /* geniCodeIfx - generates code for extended if statement */
2804 /*-----------------------------------------------------------------*/
2806 geniCodeIfx (ast * tree,int lvl)
2809 operand *condition = ast2iCode (tree->left,lvl+1);
2812 /* if condition is null then exit */
2816 condition = geniCodeRValue (condition, FALSE);
2818 cetype = getSpec (operandType (condition));
2819 /* if the condition is a literal */
2820 if (IS_LITERAL (cetype))
2822 if (floatFromVal (condition->operand.valOperand))
2824 if (tree->trueLabel)
2825 geniCodeGoto (tree->trueLabel);
2831 if (tree->falseLabel)
2832 geniCodeGoto (tree->falseLabel);
2839 if (tree->trueLabel)
2841 ic = newiCodeCondition (condition,
2846 if (tree->falseLabel)
2847 geniCodeGoto (tree->falseLabel);
2851 ic = newiCodeCondition (condition,
2858 ast2iCode (tree->right,lvl+1);
2861 /*-----------------------------------------------------------------*/
2862 /* geniCodeJumpTable - tries to create a jump table for switch */
2863 /*-----------------------------------------------------------------*/
2865 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2867 int min = 0, max = 0, t, cnt = 0;
2874 if (!tree || !caseVals)
2877 /* the criteria for creating a jump table is */
2878 /* all integer numbers between the maximum & minimum must */
2879 /* be present , the maximum value should not exceed 255 */
2880 min = max = (int) floatFromVal (vch = caseVals);
2881 sprintf (buffer, "_case_%d_%d",
2882 tree->values.switchVals.swNum,
2884 addSet (&labels, newiTempLabel (buffer));
2886 /* if there is only one case value then no need */
2887 if (!(vch = vch->next))
2892 if (((t = (int) floatFromVal (vch)) - max) != 1)
2894 sprintf (buffer, "_case_%d_%d",
2895 tree->values.switchVals.swNum,
2897 addSet (&labels, newiTempLabel (buffer));
2903 /* if the number of case statements <= 2 then */
2904 /* it is not economical to create the jump table */
2905 /* since two compares are needed for boundary conditions */
2906 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2909 if (tree->values.switchVals.swDefault)
2910 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2912 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2914 falseLabel = newiTempLabel (buffer);
2916 /* so we can create a jumptable */
2917 /* first we rule out the boundary conditions */
2918 /* if only optimization says so */
2919 if (!optimize.noJTabBoundary)
2921 sym_link *cetype = getSpec (operandType (cond));
2922 /* no need to check the lower bound if
2923 the condition is unsigned & minimum value is zero */
2924 if (!(min == 0 && SPEC_USIGN (cetype)))
2926 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2927 ic = newiCodeCondition (boundary, falseLabel, NULL);
2931 /* now for upper bounds */
2932 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
2933 ic = newiCodeCondition (boundary, falseLabel, NULL);
2937 /* if the min is not zero then we no make it zero */
2940 cond = geniCodeSubtract (cond, operandFromLit (min));
2941 setOperandType (cond, UCHARTYPE);
2944 /* now create the jumptable */
2945 ic = newiCode (JUMPTABLE, NULL, NULL);
2946 IC_JTCOND (ic) = cond;
2947 IC_JTLABELS (ic) = labels;
2952 /*-----------------------------------------------------------------*/
2953 /* geniCodeSwitch - changes a switch to a if statement */
2954 /*-----------------------------------------------------------------*/
2956 geniCodeSwitch (ast * tree,int lvl)
2959 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
2960 value *caseVals = tree->values.switchVals.swVals;
2961 symbol *trueLabel, *falseLabel;
2963 /* if we can make this a jump table */
2964 if (geniCodeJumpTable (cond, caseVals, tree))
2965 goto jumpTable; /* no need for the comparison */
2967 /* for the cases defined do */
2971 operand *compare = geniCodeLogic (cond,
2972 operandFromValue (caseVals),
2975 sprintf (buffer, "_case_%d_%d",
2976 tree->values.switchVals.swNum,
2977 (int) floatFromVal (caseVals));
2978 trueLabel = newiTempLabel (buffer);
2980 ic = newiCodeCondition (compare, trueLabel, NULL);
2982 caseVals = caseVals->next;
2987 /* if default is present then goto break else break */
2988 if (tree->values.switchVals.swDefault)
2989 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2991 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2993 falseLabel = newiTempLabel (buffer);
2994 geniCodeGoto (falseLabel);
2997 ast2iCode (tree->right,lvl+1);
3000 /*-----------------------------------------------------------------*/
3001 /* geniCodeInline - intermediate code for inline assembler */
3002 /*-----------------------------------------------------------------*/
3004 geniCodeInline (ast * tree)
3008 ic = newiCode (INLINEASM, NULL, NULL);
3009 IC_INLINE (ic) = tree->values.inlineasm;
3013 /*-----------------------------------------------------------------*/
3014 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3015 /* particular case. Ie : assigning or dereferencing array or ptr */
3016 /*-----------------------------------------------------------------*/
3017 set * lvaluereqSet = NULL;
3018 typedef struct lvalItem
3025 /*-----------------------------------------------------------------*/
3026 /* addLvaluereq - add a flag for lvalreq for current ast level */
3027 /*-----------------------------------------------------------------*/
3028 void addLvaluereq(int lvl)
3030 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3033 addSetHead(&lvaluereqSet,lpItem);
3036 /*-----------------------------------------------------------------*/
3037 /* delLvaluereq - del a flag for lvalreq for current ast level */
3038 /*-----------------------------------------------------------------*/
3042 lpItem = getSet(&lvaluereqSet);
3043 if(lpItem) free(lpItem);
3045 /*-----------------------------------------------------------------*/
3046 /* clearLvaluereq - clear lvalreq flag */
3047 /*-----------------------------------------------------------------*/
3048 void clearLvaluereq()
3051 lpItem = peekSet(lvaluereqSet);
3052 if(lpItem) lpItem->req = 0;
3054 /*-----------------------------------------------------------------*/
3055 /* getLvaluereq - get the last lvalreq level */
3056 /*-----------------------------------------------------------------*/
3057 int getLvaluereqLvl()
3060 lpItem = peekSet(lvaluereqSet);
3061 if(lpItem) return lpItem->lvl;
3064 /*-----------------------------------------------------------------*/
3065 /* isLvaluereq - is lvalreq valid for this level ? */
3066 /*-----------------------------------------------------------------*/
3067 int isLvaluereq(int lvl)
3070 lpItem = peekSet(lvaluereqSet);
3071 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3075 /*-----------------------------------------------------------------*/
3076 /* ast2iCode - creates an icodeList from an ast */
3077 /*-----------------------------------------------------------------*/
3079 ast2iCode (ast * tree,int lvl)
3081 operand *left = NULL;
3082 operand *right = NULL;
3085 /* set the global variables for filename & line number */
3087 filename = tree->filename;
3089 lineno = tree->lineno;
3091 block = tree->block;
3093 scopeLevel = tree->level;
3095 if (tree->type == EX_VALUE)
3096 return operandFromValue (tree->opval.val);
3098 if (tree->type == EX_LINK)
3099 return operandFromLink (tree->opval.lnk);
3101 /* if we find a nullop */
3102 if (tree->type == EX_OP &&
3103 (tree->opval.op == NULLOP ||
3104 tree->opval.op == BLOCK))
3106 ast2iCode (tree->left,lvl+1);
3107 ast2iCode (tree->right,lvl+1);
3111 /* special cases for not evaluating */
3112 if (tree->opval.op != ':' &&
3113 tree->opval.op != '?' &&
3114 tree->opval.op != CALL &&
3115 tree->opval.op != IFX &&
3116 tree->opval.op != LABEL &&
3117 tree->opval.op != GOTO &&
3118 tree->opval.op != SWITCH &&
3119 tree->opval.op != FUNCTION &&
3120 tree->opval.op != INLINEASM)
3123 if (IS_ASSIGN_OP (tree->opval.op) ||
3124 IS_DEREF_OP (tree) ||
3125 (tree->opval.op == '&' && !tree->right) ||
3126 tree->opval.op == PTR_OP)
3129 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3130 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3133 left = operandFromAst (tree->left,lvl);
3135 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3136 left = geniCodeRValue (left, TRUE);
3140 left = operandFromAst (tree->left,lvl);
3142 if (tree->opval.op == INC_OP ||
3143 tree->opval.op == DEC_OP)
3146 right = operandFromAst (tree->right,lvl);
3151 right = operandFromAst (tree->right,lvl);
3155 /* now depending on the type of operand */
3156 /* this will be a biggy */
3157 switch (tree->opval.op)
3160 case '[': /* array operation */
3162 sym_link *ltype = operandType (left);
3163 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3164 right = geniCodeRValue (right, TRUE);
3167 return geniCodeArray (left, right,lvl);
3169 case '.': /* structure dereference */
3170 if (IS_PTR (operandType (left)))
3171 left = geniCodeRValue (left, TRUE);
3173 left = geniCodeRValue (left, FALSE);
3175 return geniCodeStruct (left, right, tree->lvalue);
3177 case PTR_OP: /* structure pointer dereference */
3180 pType = operandType (left);
3181 left = geniCodeRValue (left, TRUE);
3183 setOClass (pType, getSpec (operandType (left)));
3186 return geniCodeStruct (left, right, tree->lvalue);
3188 case INC_OP: /* increment operator */
3190 return geniCodePostInc (left);
3192 return geniCodePreInc (right);
3194 case DEC_OP: /* decrement operator */
3196 return geniCodePostDec (left);
3198 return geniCodePreDec (right);
3200 case '&': /* bitwise and or address of operator */
3202 { /* this is a bitwise operator */
3203 left = geniCodeRValue (left, FALSE);
3204 right = geniCodeRValue (right, FALSE);
3205 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3208 return geniCodeAddressOf (left);
3210 case '|': /* bitwise or & xor */
3212 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3213 geniCodeRValue (right, FALSE),
3218 return geniCodeDivision (geniCodeRValue (left, FALSE),
3219 geniCodeRValue (right, FALSE));
3222 return geniCodeModulus (geniCodeRValue (left, FALSE),
3223 geniCodeRValue (right, FALSE));
3226 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3227 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3229 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3233 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3234 geniCodeRValue (right, FALSE));
3236 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3240 return geniCodeAdd (geniCodeRValue (left, FALSE),
3241 geniCodeRValue (right, FALSE),lvl);
3243 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3246 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3247 geniCodeRValue (right, FALSE));
3250 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3251 geniCodeRValue (right, FALSE));
3253 return geniCodeCast (operandType (left),
3254 geniCodeRValue (right, FALSE), FALSE);
3260 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3264 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3265 setOperandType (op, UCHARTYPE);
3276 return geniCodeLogic (geniCodeRValue (left, FALSE),
3277 geniCodeRValue (right, FALSE),
3280 return geniCodeConditional (tree,lvl);
3283 return operandFromLit (getSize (tree->right->ftype));
3287 sym_link *rtype = operandType (right);
3288 sym_link *ltype = operandType (left);
3289 if (IS_PTR (rtype) && IS_ITEMP (right)
3290 && right->isaddr && checkType (rtype->next, ltype) == 1)
3291 right = geniCodeRValue (right, TRUE);
3293 right = geniCodeRValue (right, FALSE);
3295 geniCodeAssign (left, right, 0);
3300 geniCodeAssign (left,
3301 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3303 geniCodeRValue (right, FALSE),FALSE), 0);
3307 geniCodeAssign (left,
3308 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3310 geniCodeRValue (right, FALSE)), 0);
3313 geniCodeAssign (left,
3314 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3316 geniCodeRValue (right, FALSE)), 0);
3319 sym_link *rtype = operandType (right);
3320 sym_link *ltype = operandType (left);
3321 if (IS_PTR (rtype) && IS_ITEMP (right)
3322 && right->isaddr && checkType (rtype->next, ltype) == 1)
3323 right = geniCodeRValue (right, TRUE);
3325 right = geniCodeRValue (right, FALSE);
3328 return geniCodeAssign (left,
3329 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3335 sym_link *rtype = operandType (right);
3336 sym_link *ltype = operandType (left);
3337 if (IS_PTR (rtype) && IS_ITEMP (right)
3338 && right->isaddr && checkType (rtype->next, ltype) == 1)
3340 right = geniCodeRValue (right, TRUE);
3344 right = geniCodeRValue (right, FALSE);
3347 geniCodeAssign (left,
3348 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3354 geniCodeAssign (left,
3355 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3357 geniCodeRValue (right, FALSE)), 0);
3360 geniCodeAssign (left,
3361 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3363 geniCodeRValue (right, FALSE)), 0);
3366 geniCodeAssign (left,
3367 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3369 geniCodeRValue (right, FALSE),
3371 operandType (left)), 0);
3374 geniCodeAssign (left,
3375 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3377 geniCodeRValue (right, FALSE),
3379 operandType (left)), 0);
3382 geniCodeAssign (left,
3383 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3385 geniCodeRValue (right, FALSE),
3387 operandType (left)), 0);
3389 return geniCodeRValue (right, FALSE);
3392 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3395 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3396 return ast2iCode (tree->right,lvl+1);
3399 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3400 return ast2iCode (tree->right,lvl+1);
3403 geniCodeFunctionBody (tree,lvl);
3407 geniCodeReturn (right);
3411 geniCodeIfx (tree,lvl);
3415 geniCodeSwitch (tree,lvl);
3419 geniCodeInline (tree);
3426 /*-----------------------------------------------------------------*/
3427 /* reverseICChain - gets from the list and creates a linkedlist */
3428 /*-----------------------------------------------------------------*/
3435 while ((loop = getSet (&iCodeChain)))
3447 /*-----------------------------------------------------------------*/
3448 /* iCodeFromAst - given an ast will convert it to iCode */
3449 /*-----------------------------------------------------------------*/
3451 iCodeFromAst (ast * tree)
3453 returnLabel = newiTempLabel ("_return");
3454 entryLabel = newiTempLabel ("_entry");
3456 return reverseiCChain ();