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;
42 symbol *returnLabel; /* function return label */
43 symbol *entryLabel; /* function entry label */
44 /*-----------------------------------------------------------------*/
45 /* forward definition of some functions */
46 operand *geniCodeDivision (operand *, operand *);
47 operand *geniCodeAssign (operand *, operand *, int);
48 operand *geniCodeArray (operand *, operand *);
49 operand *geniCodeArray2Ptr (operand *);
50 operand *geniCodeRValue (operand *, bool);
51 operand *geniCodeDerefPtr (operand *);
53 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
54 /* forward definition of 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);
401 /*-----------------------------------------------------------------*/
402 /* printiCChain - prints intermediate code for humans */
403 /*-----------------------------------------------------------------*/
405 printiCChain (iCode * icChain, FILE * of)
412 for (loop = icChain; loop; loop = loop->next)
414 if ((icTab = getTableEntry (loop->op)))
416 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
417 loop->filename, loop->lineno,
418 loop->seq, loop->key, loop->depth, loop->supportRtn);
420 icTab->iCodePrint (of, loop, icTab->printName);
426 /*-----------------------------------------------------------------*/
427 /* newOperand - allocate, init & return a new iCode */
428 /*-----------------------------------------------------------------*/
434 op = Safe_calloc (1, sizeof (operand));
440 /*-----------------------------------------------------------------*/
441 /* newiCode - create and return a new iCode entry initialised */
442 /*-----------------------------------------------------------------*/
444 newiCode (int op, operand * left, operand * right)
448 ic = Safe_calloc (1, sizeof (iCode));
451 ic->filename = filename;
453 ic->level = scopeLevel;
455 ic->key = iCodeKey++;
457 IC_RIGHT (ic) = right;
462 /*-----------------------------------------------------------------*/
463 /* newiCode for conditional statements */
464 /*-----------------------------------------------------------------*/
466 newiCodeCondition (operand * condition,
472 ic = newiCode (IFX, NULL, NULL);
473 IC_COND (ic) = condition;
474 IC_TRUE (ic) = trueLabel;
475 IC_FALSE (ic) = falseLabel;
479 /*-----------------------------------------------------------------*/
480 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
481 /*-----------------------------------------------------------------*/
483 newiCodeLabelGoto (int op, symbol * label)
487 ic = newiCode (op, NULL, NULL);
489 ic->argLabel.label = label;
491 IC_RIGHT (ic) = NULL;
492 IC_RESULT (ic) = NULL;
496 /*-----------------------------------------------------------------*/
497 /* newiTemp - allocate & return a newItemp Variable */
498 /*-----------------------------------------------------------------*/
505 sprintf (buffer, "%s", s);
507 sprintf (buffer, "iTemp%d", iTempNum++);
508 itmp = newSymbol (buffer, 1);
509 strcpy (itmp->rname, itmp->name);
515 /*-----------------------------------------------------------------*/
516 /* newiTempLabel - creates a temp variable label */
517 /*-----------------------------------------------------------------*/
519 newiTempLabel (char *s)
523 /* check if this alredy exists */
524 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
528 itmplbl = newSymbol (s, 1);
531 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
532 itmplbl = newSymbol (buffer, 1);
537 itmplbl->key = labelKey++;
538 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
542 /*-----------------------------------------------------------------*/
543 /* newiTempPreheaderLabel - creates a new preheader label */
544 /*-----------------------------------------------------------------*/
546 newiTempPreheaderLabel ()
550 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
551 itmplbl = newSymbol (buffer, 1);
555 itmplbl->key = labelKey++;
556 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
561 /*-----------------------------------------------------------------*/
562 /* initiCode - initialises some iCode related stuff */
563 /*-----------------------------------------------------------------*/
570 /*-----------------------------------------------------------------*/
571 /* copyiCode - make a copy of the iCode given */
572 /*-----------------------------------------------------------------*/
574 copyiCode (iCode * ic)
576 iCode *nic = newiCode (ic->op, NULL, NULL);
578 nic->lineno = ic->lineno;
579 nic->filename = ic->filename;
580 nic->block = ic->block;
581 nic->level = ic->level;
583 /* deal with the special cases first */
587 IC_COND (nic) = operandFromOperand (IC_COND (ic));
588 IC_TRUE (nic) = IC_TRUE (ic);
589 IC_FALSE (nic) = IC_FALSE (ic);
593 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
594 IC_JTLABELS (nic) = IC_JTLABELS (ic);
599 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
600 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
601 IC_ARGS (nic) = IC_ARGS (ic);
605 IC_INLINE (nic) = IC_INLINE (ic);
609 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
610 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
611 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
617 /*-----------------------------------------------------------------*/
618 /* getTableEntry - gets the table entry for the given operator */
619 /*-----------------------------------------------------------------*/
621 getTableEntry (int oper)
625 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
626 if (oper == codeTable[i].icode)
627 return &codeTable[i];
632 /*-----------------------------------------------------------------*/
633 /* newiTempOperand - new intermediate temp operand */
634 /*-----------------------------------------------------------------*/
636 newiTempOperand (sym_link * type, char throwType)
639 operand *op = newOperand ();
643 itmp = newiTemp (NULL);
645 etype = getSpec (type);
647 if (IS_LITERAL (etype))
650 /* copy the type information */
652 itmp->etype = getSpec (itmp->type = (throwType ? type :
653 copyLinkChain (type)));
654 if (IS_LITERAL (itmp->etype))
656 SPEC_SCLS (itmp->etype) = S_REGISTER;
657 SPEC_OCLS (itmp->etype) = reg;
660 op->operand.symOperand = itmp;
661 op->key = itmp->key = ++operandKey;
665 /*-----------------------------------------------------------------*/
666 /* operandType - returns the type chain for an operand */
667 /*-----------------------------------------------------------------*/
669 operandType (operand * op)
671 /* depending on type of operand */
676 return op->operand.valOperand->type;
679 return op->operand.symOperand->type;
682 return op->operand.typeOperand;
684 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
685 " operand type not known ");
686 assert (0); /* should never come here */
687 /* Just to keep the compiler happy */
688 return (sym_link *) 0;
692 /*-----------------------------------------------------------------*/
693 /* isParamterToCall - will return 1 if op is a parameter to args */
694 /*-----------------------------------------------------------------*/
696 isParameterToCall (value * args, operand * op)
703 isSymbolEqual (op->operand.symOperand, tval->sym))
710 /*-----------------------------------------------------------------*/
711 /* isOperandGlobal - return 1 if operand is a global variable */
712 /*-----------------------------------------------------------------*/
714 isOperandGlobal (operand * op)
722 if (op->type == SYMBOL &&
723 (op->operand.symOperand->level == 0 ||
724 IS_STATIC (op->operand.symOperand->etype) ||
725 IS_EXTERN (op->operand.symOperand->etype))
732 /*-----------------------------------------------------------------*/
733 /* isOperandVolatile - return 1 if the operand is volatile */
734 /*-----------------------------------------------------------------*/
736 isOperandVolatile (operand * op, bool chkTemp)
741 if (IS_ITEMP (op) && !chkTemp)
744 opetype = getSpec (optype = operandType (op));
746 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
749 if (IS_VOLATILE (opetype))
754 /*-----------------------------------------------------------------*/
755 /* isOperandLiteral - returns 1 if an operand contains a literal */
756 /*-----------------------------------------------------------------*/
758 isOperandLiteral (operand * op)
765 opetype = getSpec (operandType (op));
767 if (IS_LITERAL (opetype))
772 /*-----------------------------------------------------------------*/
773 /* isOperandInFarSpace - will return true if operand is in farSpace */
774 /*-----------------------------------------------------------------*/
776 isOperandInFarSpace (operand * op)
786 if (!IS_TRUE_SYMOP (op))
789 etype = SPIL_LOC (op)->etype;
795 etype = getSpec (operandType (op));
797 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
800 /*-----------------------------------------------------------------*/
801 /* isOperandOnStack - will return true if operand is on stack */
802 /*-----------------------------------------------------------------*/
804 isOperandOnStack (operand * op)
814 etype = getSpec (operandType (op));
816 return ((IN_STACK (etype)) ? TRUE : FALSE);
819 /*-----------------------------------------------------------------*/
820 /* operandLitValue - literal value of an operand */
821 /*-----------------------------------------------------------------*/
823 operandLitValue (operand * op)
825 assert (isOperandLiteral (op));
827 return floatFromVal (op->operand.valOperand);
830 /*-----------------------------------------------------------------*/
831 /* operandOperation - perforoms operations on operands */
832 /*-----------------------------------------------------------------*/
834 operandOperation (operand * left, operand * right,
835 int op, sym_link * type)
837 operand *retval = (operand *) 0;
839 assert (isOperandLiteral (left));
841 assert (isOperandLiteral (right));
846 retval = operandFromValue (valCastLiteral (type,
847 operandLitValue (left) +
848 operandLitValue (right)));
851 retval = operandFromValue (valCastLiteral (type,
852 operandLitValue (left) -
853 operandLitValue (right)));
856 retval = operandFromValue (valCastLiteral (type,
857 operandLitValue (left) *
858 operandLitValue (right)));
861 if ((unsigned long) operandLitValue (right) == 0)
863 werror (E_DIVIDE_BY_ZERO);
868 retval = operandFromValue (valCastLiteral (type,
869 operandLitValue (left) /
870 operandLitValue (right)));
873 if ((unsigned long) operandLitValue (right) == 0)
875 werror (E_DIVIDE_BY_ZERO);
879 retval = operandFromLit ((unsigned long) operandLitValue (left) %
880 (unsigned long) operandLitValue (right));
883 retval = operandFromLit ((unsigned long) operandLitValue (left) <<
884 (unsigned long) operandLitValue (right));
887 retval = operandFromLit ((unsigned long) operandLitValue (left) >>
888 (unsigned long) operandLitValue (right));
891 retval = operandFromLit (operandLitValue (left) ==
892 operandLitValue (right));
895 retval = operandFromLit (operandLitValue (left) <
896 operandLitValue (right));
899 retval = operandFromLit (operandLitValue (left) <=
900 operandLitValue (right));
903 retval = operandFromLit (operandLitValue (left) !=
904 operandLitValue (right));
907 retval = operandFromLit (operandLitValue (left) >
908 operandLitValue (right));
911 retval = operandFromLit (operandLitValue (left) >=
912 operandLitValue (right));
915 retval = operandFromLit ((unsigned long) operandLitValue (left) &
916 (unsigned long) operandLitValue (right));
919 retval = operandFromLit ((unsigned long) operandLitValue (left) |
920 (unsigned long) operandLitValue (right));
923 retval = operandFromLit ((unsigned long) operandLitValue (left) ^
924 (unsigned long) operandLitValue (right));
927 retval = operandFromLit (operandLitValue (left) &&
928 operandLitValue (right));
931 retval = operandFromLit (operandLitValue (left) ||
932 operandLitValue (right));
936 long i = operandLitValue (left);
938 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
944 long i = operandLitValue (left);
946 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
952 retval = operandFromLit (-1 * operandLitValue (left));
956 retval = operandFromLit (~((long) operandLitValue (left)));
960 retval = operandFromLit (!operandLitValue (left));
964 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
965 " operandOperation invalid operator ");
973 /*-----------------------------------------------------------------*/
974 /* isOperandEqual - compares two operand & return 1 if they r = */
975 /*-----------------------------------------------------------------*/
977 isOperandEqual (operand * left, operand * right)
979 /* if the pointers are equal then they are equal */
983 /* if either of them null then false */
987 if (left->type != right->type)
990 if (IS_SYMOP (left) && IS_SYMOP (right))
991 return left->key == right->key;
993 /* if types are the same */
997 return isSymbolEqual (left->operand.symOperand,
998 right->operand.symOperand);
1000 return (floatFromVal (left->operand.valOperand) ==
1001 floatFromVal (right->operand.valOperand));
1003 if (checkType (left->operand.typeOperand,
1004 right->operand.typeOperand) == 1)
1011 /*-----------------------------------------------------------------*/
1012 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1013 /*-----------------------------------------------------------------*/
1015 isiCodeEqual (iCode * left, iCode * right)
1017 /* if the same pointer */
1021 /* if either of them null */
1022 if (!left || !right)
1025 /* if operand are the same */
1026 if (left->op == right->op)
1029 /* compare all the elements depending on type */
1030 if (left->op != IFX)
1032 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1034 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1040 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1042 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1044 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1052 /*-----------------------------------------------------------------*/
1053 /* newiTempFromOp - create a temp Operand with same attributes */
1054 /*-----------------------------------------------------------------*/
1056 newiTempFromOp (operand * op)
1066 nop = newiTempOperand (operandType (op), TRUE);
1067 nop->isaddr = op->isaddr;
1068 nop->isvolatile = op->isvolatile;
1069 nop->isGlobal = op->isGlobal;
1070 nop->isLiteral = op->isLiteral;
1071 nop->noSpilLoc = op->noSpilLoc;
1072 nop->usesDefs = op->usesDefs;
1073 nop->isParm = op->isParm;
1074 nop->parmBytes = op->parmBytes;
1078 /*-----------------------------------------------------------------*/
1079 /* operand from operand - creates an operand holder for the type */
1080 /*-----------------------------------------------------------------*/
1082 operandFromOperand (operand * op)
1088 nop = newOperand ();
1089 nop->type = op->type;
1090 nop->isaddr = op->isaddr;
1092 nop->isvolatile = op->isvolatile;
1093 nop->isGlobal = op->isGlobal;
1094 nop->isLiteral = op->isLiteral;
1095 nop->noSpilLoc = op->noSpilLoc;
1096 nop->usesDefs = op->usesDefs;
1097 nop->isParm = op->isParm;
1098 nop->parmBytes = op->parmBytes;
1103 nop->operand.symOperand = op->operand.symOperand;
1106 nop->operand.valOperand = op->operand.valOperand;
1109 nop->operand.typeOperand = op->operand.typeOperand;
1116 /*-----------------------------------------------------------------*/
1117 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1118 /*-----------------------------------------------------------------*/
1120 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1122 operand *nop = operandFromOperand (op);
1124 if (nop->type == SYMBOL)
1126 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1127 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1133 /*-----------------------------------------------------------------*/
1134 /* operandFromSymbol - creates an operand from a symbol */
1135 /*-----------------------------------------------------------------*/
1137 operandFromSymbol (symbol * sym)
1142 /* if the symbol's type is a literal */
1143 /* then it is an enumerator type */
1144 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1145 return operandFromValue (valFromType (sym->etype));
1148 sym->key = ++operandKey;
1150 /* if this an implicit variable, means struct/union */
1151 /* member so just return it */
1152 if (sym->implicit || IS_FUNC (sym->type))
1156 op->operand.symOperand = sym;
1158 op->isvolatile = isOperandVolatile (op, TRUE);
1159 op->isGlobal = isOperandGlobal (op);
1160 op->parmBytes = sym->argStack;
1164 /* under the following conditions create a
1165 register equivalent for a local symbol */
1166 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1167 (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!IS_DS390_PORT)) &&
1168 options.stackAuto == 0)
1171 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1172 !IS_FUNC (sym->type) && /* not a function */
1173 !sym->_isparm && /* not a parameter */
1174 sym->level && /* is a local variable */
1175 !sym->addrtaken && /* whose address has not been taken */
1176 !sym->reqv && /* does not already have a register euivalence */
1177 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1178 !IS_STATIC (sym->etype) && /* and not declared static */
1179 !sym->islbl && /* not a label */
1180 ok && /* farspace check */
1181 !IS_BITVAR (sym->etype) /* not a bit variable */
1185 /* we will use it after all optimizations
1186 and before liveRange calculation */
1187 sym->reqv = newiTempOperand (sym->type, 0);
1188 sym->reqv->key = sym->key;
1189 OP_SYMBOL (sym->reqv)->key = sym->key;
1190 OP_SYMBOL (sym->reqv)->isreqv = 1;
1191 OP_SYMBOL (sym->reqv)->islocal = 1;
1192 SPIL_LOC (sym->reqv) = sym;
1195 if (!IS_AGGREGATE (sym->type))
1199 op->operand.symOperand = sym;
1202 op->isvolatile = isOperandVolatile (op, TRUE);
1203 op->isGlobal = isOperandGlobal (op);
1204 op->isPtr = IS_PTR (operandType (op));
1205 op->isParm = sym->_isparm;
1210 /* itemp = &[_symbol] */
1212 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1213 IC_LEFT (ic)->type = SYMBOL;
1214 IC_LEFT (ic)->operand.symOperand = sym;
1215 IC_LEFT (ic)->key = sym->key;
1216 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1217 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1218 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1221 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1222 if (IS_ARRAY (sym->type))
1224 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1225 IC_RESULT (ic)->isaddr = 0;
1228 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1230 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1234 return IC_RESULT (ic);
1237 /*-----------------------------------------------------------------*/
1238 /* operandFromValue - creates an operand from value */
1239 /*-----------------------------------------------------------------*/
1241 operandFromValue (value * val)
1245 /* if this is a symbol then do the symbol thing */
1247 return operandFromSymbol (val->sym);
1249 /* this is not a symbol */
1252 op->operand.valOperand = val;
1253 op->isLiteral = isOperandLiteral (op);
1257 /*-----------------------------------------------------------------*/
1258 /* operandFromLink - operand from typeChain */
1259 /*-----------------------------------------------------------------*/
1261 operandFromLink (sym_link * type)
1265 /* operand from sym_link */
1271 op->operand.typeOperand = copyLinkChain (type);
1275 /*-----------------------------------------------------------------*/
1276 /* operandFromLit - makes an operand from a literal value */
1277 /*-----------------------------------------------------------------*/
1279 operandFromLit (float i)
1281 return operandFromValue (valueFromLit (i));
1284 /*-----------------------------------------------------------------*/
1285 /* operandFromAst - creates an operand from an ast */
1286 /*-----------------------------------------------------------------*/
1288 operandFromAst (ast * tree)
1294 /* depending on type do */
1298 return ast2iCode (tree);
1302 return operandFromValue (tree->opval.val);
1306 return operandFromLink (tree->opval.lnk);
1310 /* Just to keep the comiler happy */
1311 return (operand *) 0;
1314 /*-----------------------------------------------------------------*/
1315 /* setOperandType - sets the operand's type to the given type */
1316 /*-----------------------------------------------------------------*/
1318 setOperandType (operand * op, sym_link * type)
1320 /* depending on the type of operand */
1325 op->operand.valOperand->etype =
1326 getSpec (op->operand.valOperand->type =
1327 copyLinkChain (type));
1331 if (op->operand.symOperand->isitmp)
1332 op->operand.symOperand->etype =
1333 getSpec (op->operand.symOperand->type =
1334 copyLinkChain (type));
1336 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1337 "attempt to modify type of source");
1341 op->operand.typeOperand = copyLinkChain (type);
1347 /*-----------------------------------------------------------------*/
1348 /* perform "usual unary conversions" */
1349 /*-----------------------------------------------------------------*/
1351 usualUnaryConversions (operand * op)
1353 if (IS_INTEGRAL (operandType (op)))
1355 if (getSize (operandType (op)) < INTSIZE)
1358 return geniCodeCast (INTTYPE, op, TRUE);
1364 /*-----------------------------------------------------------------*/
1365 /* perform "usual binary conversions" */
1366 /*-----------------------------------------------------------------*/
1368 usualBinaryConversions (operand ** op1, operand ** op2)
1370 if (!options.ANSIint)
1372 /* "Classic" SDCC behavior. */
1374 sym_link *rtype = operandType (*op2);
1375 sym_link *ltype = operandType (*op1);
1377 ctype = computeType (ltype, rtype);
1378 *op1 = geniCodeCast (ctype, *op1, TRUE);
1379 *op2 = geniCodeCast (ctype, *op2, TRUE);
1384 *op1 = usualUnaryConversions (*op1);
1385 *op2 = usualUnaryConversions (*op2);
1387 /* Try to make the two operands of the same type, following
1388 * the "usual binary conversions" promotion rules.
1390 * NB: floating point types are not yet properly handled; we
1391 * follow the "classic" behavior.
1394 if (IS_FLOAT (operandType (*op1)) || IS_FLOAT (operandType (*op2)))
1396 return newFloatLink ();
1399 if (!IS_INTEGRAL (operandType (*op1)) || !IS_INTEGRAL (operandType (*op2)))
1401 /* if either is not an integer type, we're done. */
1402 return copyLinkChain (operandType (*op1)); /* Punt! we should never get here. */
1405 /* If either is an unsigned long, make sure both are. */
1406 if (SPEC_USIGN (operandType (*op1)) && IS_LONG (operandType (*op1)))
1408 if (!SPEC_USIGN (operandType (*op2)) || !IS_LONG (operandType (*op2)))
1410 *op2 = geniCodeCast (ULONGTYPE, *op2, TRUE);
1412 return copyLinkChain (operandType (*op1));
1415 if (SPEC_USIGN (operandType (*op2)) && IS_LONG (operandType (*op2)))
1417 if (!SPEC_USIGN (operandType (*op1)) || !IS_LONG (operandType (*op1)))
1419 *op1 = geniCodeCast (ULONGTYPE, *op1, TRUE);
1421 return copyLinkChain (operandType (*op2));
1424 /* Next, if one is long and the other is int (signed or un),
1425 * cast both to long.
1427 * Note that because in our environment a long can hold all
1428 * the values of an unsigned int, the "long/unsigned int" pair
1429 * in the ANSI conversion table is unnecessary; this test
1430 * handles that case implicitly.
1432 if (IS_LONG (operandType (*op1)))
1434 /* NB: because of the unary conversions, op2 cannot
1435 * be smaller than int. Therefore, if it is not
1436 * long, it is a regular int.
1438 if (!IS_LONG (operandType (*op2)))
1440 *op2 = geniCodeCast (LONGTYPE, *op2, TRUE);
1442 return copyLinkChain (operandType (*op1));
1445 if (IS_LONG (operandType (*op2)))
1447 /* NB: because of the unary conversions, op2 cannot
1448 * be smaller than int. Therefore, if it is not
1449 * long, it is a regular int.
1451 if (!IS_LONG (operandType (*op1)))
1453 *op1 = geniCodeCast (LONGTYPE, *op1, TRUE);
1455 return copyLinkChain (operandType (*op2));
1458 /* All right, neither is long; they must both be integers.
1460 * Only remaining issue is signed vs. unsigned; if one is unsigned
1461 * and the other isn't, convert both to unsigned.
1463 if (SPEC_USIGN (operandType (*op1)))
1465 if (!SPEC_USIGN (operandType (*op2)))
1467 *op2 = geniCodeCast (UINTTYPE, *op2, TRUE);
1469 return copyLinkChain (operandType (*op1));
1472 if (SPEC_USIGN (operandType (*op2)))
1474 if (!SPEC_USIGN (operandType (*op1)))
1476 *op1 = geniCodeCast (UINTTYPE, *op1, TRUE);
1478 return copyLinkChain (operandType (*op2));
1482 return copyLinkChain (operandType (*op1));
1486 /*-----------------------------------------------------------------*/
1487 /* geniCodeValueAtAddress - generate intermeditate code for value */
1489 /*-----------------------------------------------------------------*/
1491 geniCodeRValue (operand * op, bool force)
1494 sym_link *type = operandType (op);
1495 sym_link *etype = getSpec (type);
1497 /* if this is an array & already */
1498 /* an address then return this */
1499 if (IS_AGGREGATE (type) ||
1500 (IS_PTR (type) && !force && !op->isaddr))
1501 return operandFromOperand (op);
1503 /* if this is not an address then must be */
1504 /* rvalue already so return this one */
1508 /* if this is not a temp symbol then */
1509 if (!IS_ITEMP (op) &&
1511 !IN_FARSPACE (SPEC_OCLS (etype)))
1513 op = operandFromOperand (op);
1518 if (IS_SPEC (type) &&
1519 IS_TRUE_SYMOP (op) &&
1520 (!IN_FARSPACE (SPEC_OCLS (etype)) || IS_DS390_PORT))
1522 op = operandFromOperand (op);
1527 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1528 if (IS_PTR (type) && op->isaddr && force)
1531 type = copyLinkChain (type);
1533 IC_RESULT (ic) = newiTempOperand (type, 1);
1534 IC_RESULT (ic)->isaddr = 0;
1536 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1538 /* if the right is a symbol */
1539 if (op->type == SYMBOL)
1540 IC_RESULT (ic)->operand.symOperand->args =
1541 op->operand.symOperand->args;
1544 return IC_RESULT (ic);
1547 /*-----------------------------------------------------------------*/
1548 /* geniCodeCast - changes the value from one type to another */
1549 /*-----------------------------------------------------------------*/
1551 geniCodeCast (sym_link * type, operand * op, bool implicit)
1555 sym_link *opetype = getSpec (optype = operandType (op));
1558 /* one of them has size zero then error */
1559 if (IS_VOID (optype))
1561 werror (E_CAST_ZERO);
1565 /* if the operand is already the desired type then do nothing */
1566 if (checkType (type, optype) == 1)
1569 /* if this is a literal then just change the type & return */
1570 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1571 return operandFromValue (valCastLiteral (type,
1572 operandLitValue (op)));
1574 /* if casting to some pointer type &&
1575 the destination is not a generic pointer
1576 then give a warning : (only for implicit casts) */
1577 if (IS_PTR (optype) && implicit &&
1578 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1581 werror (E_INCOMPAT_CAST);
1582 werror (E_CONTINUE, "from type '");
1583 printTypeChain (optype, stderr);
1584 fprintf (stderr, "' to type '");
1585 printTypeChain (type, stderr);
1586 fprintf (stderr, "'\n");
1589 /* if they are the same size create an assignment */
1590 if (getSize (type) == getSize (optype) &&
1591 !IS_BITFIELD (type) &&
1593 !IS_FLOAT (optype) &&
1594 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1595 (!IS_SPEC (type) && !IS_SPEC (optype))))
1598 ic = newiCode ('=', NULL, op);
1599 IC_RESULT (ic) = newiTempOperand (type, 0);
1600 SPIL_LOC (IC_RESULT (ic)) =
1601 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1602 IC_RESULT (ic)->isaddr = 0;
1606 ic = newiCode (CAST, operandFromLink (type),
1607 geniCodeRValue (op, FALSE));
1609 IC_RESULT (ic) = newiTempOperand (type, 0);
1612 /* preserve the storage class & output class */
1613 /* of the original variable */
1614 restype = getSpec (operandType (IC_RESULT (ic)));
1615 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1616 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1619 return IC_RESULT (ic);
1622 /*-----------------------------------------------------------------*/
1623 /* geniCodeLabel - will create a Label */
1624 /*-----------------------------------------------------------------*/
1626 geniCodeLabel (symbol * label)
1630 ic = newiCodeLabelGoto (LABEL, label);
1634 /*-----------------------------------------------------------------*/
1635 /* geniCodeGoto - will create a Goto */
1636 /*-----------------------------------------------------------------*/
1638 geniCodeGoto (symbol * label)
1642 ic = newiCodeLabelGoto (GOTO, label);
1646 /*-----------------------------------------------------------------*/
1647 /* geniCodeMultiply - gen intermediate code for multiplication */
1648 /*-----------------------------------------------------------------*/
1650 geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation)
1658 /* if they are both literal then we know the result */
1659 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1660 return operandFromValue (valMult (left->operand.valOperand,
1661 right->operand.valOperand));
1664 //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size
1665 if ((ptrSizeCalculation) && (1 == getSize (rtype)) &&
1666 (1 == getSize (ltype)))
1668 saveOption = options.ANSIint;
1669 options.ANSIint = 0;
1670 resType = usualBinaryConversions (&left, &right);
1671 ltype = operandType (left);
1672 rtype = operandType (right);
1673 SPEC_SHORT (getSpec (resType)) = 0;
1674 options.ANSIint = saveOption;
1677 resType = usualBinaryConversions (&left, &right);
1678 if (IS_DS390_PORT) {
1679 /* jwk char*char=int
1680 Now be can use the 16bit result of "mul a,b" instead of explicit
1681 casts and support function calls as with --ansiint
1683 if ((IS_CHAR(letype) || IS_SHORT(letype)) &&
1684 (IS_CHAR(retype) || IS_SHORT(retype))) {
1685 SPEC_NOUN(getSpec(resType))=V_INT;
1686 SPEC_SHORT(getSpec(resType))=0;
1691 /* if the right is a literal & power of 2 */
1692 /* then make it a left shift */
1693 /*If we are computing ptr size then normal multiplication */
1694 /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
1695 /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
1696 if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
1697 !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
1698 (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
1700 if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)))
1702 /* LEFT_OP need same size for left and result, */
1703 left = geniCodeCast (resType, left, TRUE);
1704 ltype = operandType (left);
1706 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1710 ic = newiCode ('*', left, right); /* normal multiplication */
1711 /* if the size left or right > 1 then support routine */
1712 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1716 IC_RESULT (ic) = newiTempOperand (resType, 1);
1719 return IC_RESULT (ic);
1722 /*-----------------------------------------------------------------*/
1723 /* geniCodeDivision - gen intermediate code for division */
1724 /*-----------------------------------------------------------------*/
1726 geniCodeDivision (operand * left, operand * right)
1731 sym_link *rtype = operandType (right);
1732 sym_link *retype = getSpec (rtype);
1733 sym_link *ltype = operandType (left);
1734 sym_link *letype = getSpec (ltype);
1736 resType = usualBinaryConversions (&left, &right);
1738 /* if the right is a literal & power of 2 */
1739 /* then make it a right shift */
1740 if (IS_LITERAL (retype) &&
1741 !IS_FLOAT (letype) &&
1742 (p2 = powof2 ((unsigned long)
1743 floatFromVal (right->operand.valOperand))))
1744 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1747 ic = newiCode ('/', left, right); /* normal division */
1748 /* if the size left or right > 1 then support routine */
1749 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1752 IC_RESULT (ic) = newiTempOperand (resType, 0);
1755 return IC_RESULT (ic);
1757 /*-----------------------------------------------------------------*/
1758 /* geniCodeModulus - gen intermediate code for modulus */
1759 /*-----------------------------------------------------------------*/
1761 geniCodeModulus (operand * left, operand * right)
1767 /* if they are both literal then we know the result */
1768 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1769 return operandFromValue (valMod (left->operand.valOperand,
1770 right->operand.valOperand));
1772 resType = usualBinaryConversions (&left, &right);
1774 /* now they are the same size */
1775 ic = newiCode ('%', left, right);
1777 /* if the size left or right > 1 then support routine */
1778 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1780 IC_RESULT (ic) = newiTempOperand (resType, 0);
1783 return IC_RESULT (ic);
1786 /*-----------------------------------------------------------------*/
1787 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1788 /*-----------------------------------------------------------------*/
1790 geniCodePtrPtrSubtract (operand * left, operand * right)
1796 /* if they are both literals then */
1797 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1799 result = operandFromValue (valMinus (left->operand.valOperand,
1800 right->operand.valOperand));
1804 ic = newiCode ('-', left, right);
1806 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1810 return geniCodeDivision (result,
1811 operandFromLit (getSize (ltype->next)));
1814 /*-----------------------------------------------------------------*/
1815 /* geniCodeSubtract - generates code for subtraction */
1816 /*-----------------------------------------------------------------*/
1818 geniCodeSubtract (operand * left, operand * right)
1825 /* if they both pointers then */
1826 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1827 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1828 return geniCodePtrPtrSubtract (left, right);
1830 /* if they are both literal then we know the result */
1831 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1832 && left->isLiteral && right->isLiteral)
1833 return operandFromValue (valMinus (left->operand.valOperand,
1834 right->operand.valOperand));
1836 /* if left is an array or pointer */
1837 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1839 isarray = left->isaddr;
1840 right = geniCodeMultiply (right,
1841 operandFromLit (getSize (ltype->next)), TRUE);
1842 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1845 { /* make them the same size */
1846 resType = usualBinaryConversions (&left, &right);
1849 ic = newiCode ('-', left, right);
1851 IC_RESULT (ic) = newiTempOperand (resType, 1);
1852 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1854 /* if left or right is a float */
1855 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1859 return IC_RESULT (ic);
1862 /*-----------------------------------------------------------------*/
1863 /* geniCodeAdd - generates iCode for addition */
1864 /*-----------------------------------------------------------------*/
1866 geniCodeAdd (operand * left, operand * right)
1874 /* if left is an array then array access */
1875 if (IS_ARRAY (ltype))
1876 return geniCodeArray (left, right);
1878 /* if the right side is LITERAL zero */
1879 /* return the left side */
1880 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1883 /* if left is literal zero return right */
1884 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1887 /* if left is an array or pointer then size */
1891 isarray = left->isaddr;
1893 operandFromLit (getSize (ltype->next));
1895 right = geniCodeMultiply (right, size, (getSize (ltype) != 1));
1897 resType = copyLinkChain (ltype);
1900 { /* make them the same size */
1901 resType = usualBinaryConversions (&left, &right);
1904 /* if they are both literals then we know */
1905 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1906 && left->isLiteral && right->isLiteral)
1907 return operandFromValue (valPlus (valFromType (letype),
1908 valFromType (retype)));
1910 ic = newiCode ('+', left, right);
1912 IC_RESULT (ic) = newiTempOperand (resType, 1);
1913 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1915 /* if left or right is a float then support
1917 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1922 return IC_RESULT (ic);
1926 /*-----------------------------------------------------------------*/
1927 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1928 /*-----------------------------------------------------------------*/
1930 aggrToPtr (sym_link * type, bool force)
1936 if (IS_PTR (type) && !force)
1939 etype = getSpec (type);
1943 /* if the output class is generic */
1944 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1945 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1947 /* if the variable was declared a constant */
1948 /* then the pointer points to a constant */
1949 if (IS_CONSTANT (etype))
1950 DCL_PTR_CONST (ptype) = 1;
1952 /* the variable was volatile then pointer to volatile */
1953 if (IS_VOLATILE (etype))
1954 DCL_PTR_VOLATILE (ptype) = 1;
1958 /*-----------------------------------------------------------------*/
1959 /* geniCodeArray2Ptr - array to pointer */
1960 /*-----------------------------------------------------------------*/
1962 geniCodeArray2Ptr (operand * op)
1964 sym_link *optype = operandType (op);
1965 sym_link *opetype = getSpec (optype);
1967 /* set the pointer depending on the storage class */
1968 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1969 DCL_PTR_CONST (optype) = port->mem.code_ro;
1972 /* if the variable was declared a constant */
1973 /* then the pointer points to a constant */
1974 if (IS_CONSTANT (opetype))
1975 DCL_PTR_CONST (optype) = 1;
1977 /* the variable was volatile then pointer to volatile */
1978 if (IS_VOLATILE (opetype))
1979 DCL_PTR_VOLATILE (optype) = 1;
1985 /*-----------------------------------------------------------------*/
1986 /* geniCodeArray - array access */
1987 /*-----------------------------------------------------------------*/
1989 geniCodeArray (operand * left, operand * right)
1992 sym_link *ltype = operandType (left);
1996 if (IS_PTR (ltype->next) && left->isaddr)
1998 left = geniCodeRValue (left, FALSE);
2000 return geniCodeDerefPtr (geniCodeAdd (left, right));
2004 right = geniCodeMultiply (right,
2005 operandFromLit (getSize (ltype->next)), TRUE);
2007 /* we can check for limits here */
2008 if (isOperandLiteral (right) &&
2011 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2013 werror (E_ARRAY_BOUND);
2014 right = operandFromLit (0);
2017 ic = newiCode ('+', left, right);
2019 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2020 !IS_AGGREGATE (ltype->next) &&
2021 !IS_PTR (ltype->next))
2022 ? ltype : ltype->next), 0);
2024 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2026 return IC_RESULT (ic);
2029 /*-----------------------------------------------------------------*/
2030 /* geniCodeStruct - generates intermediate code for structres */
2031 /*-----------------------------------------------------------------*/
2033 geniCodeStruct (operand * left, operand * right, bool islval)
2036 sym_link *type = operandType (left);
2037 sym_link *etype = getSpec (type);
2039 symbol *element = getStructElement (SPEC_STRUCT (etype),
2040 right->operand.symOperand);
2042 /* add the offset */
2043 ic = newiCode ('+', left, operandFromLit (element->offset));
2045 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2047 /* preserve the storage & output class of the struct */
2048 /* as well as the volatile attribute */
2049 retype = getSpec (operandType (IC_RESULT (ic)));
2050 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2051 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2052 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2054 if (IS_PTR (element->type))
2055 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2057 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2061 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2064 /*-----------------------------------------------------------------*/
2065 /* geniCodePostInc - generate int code for Post increment */
2066 /*-----------------------------------------------------------------*/
2068 geniCodePostInc (operand * op)
2072 sym_link *optype = operandType (op);
2074 operand *rv = (IS_ITEMP (op) ?
2075 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2077 sym_link *rvtype = operandType (rv);
2080 /* if this is not an address we have trouble */
2083 werror (E_LVALUE_REQUIRED, "++");
2087 rOp = newiTempOperand (rvtype, 0);
2093 geniCodeAssign (rOp, rv, 0);
2095 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2096 if (IS_FLOAT (rvtype))
2097 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2099 ic = newiCode ('+', rv, operandFromLit (size));
2101 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2104 geniCodeAssign (op, result, 0);
2110 /*-----------------------------------------------------------------*/
2111 /* geniCodePreInc - generate code for preIncrement */
2112 /*-----------------------------------------------------------------*/
2114 geniCodePreInc (operand * op)
2117 sym_link *optype = operandType (op);
2118 operand *rop = (IS_ITEMP (op) ?
2119 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2121 sym_link *roptype = operandType (rop);
2127 werror (E_LVALUE_REQUIRED, "++");
2132 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2133 if (IS_FLOAT (roptype))
2134 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2136 ic = newiCode ('+', rop, operandFromLit (size));
2137 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2141 return geniCodeAssign (op, result, 0);
2144 /*-----------------------------------------------------------------*/
2145 /* geniCodePostDec - generates code for Post decrement */
2146 /*-----------------------------------------------------------------*/
2148 geniCodePostDec (operand * op)
2152 sym_link *optype = operandType (op);
2154 operand *rv = (IS_ITEMP (op) ?
2155 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2157 sym_link *rvtype = operandType (rv);
2160 /* if this is not an address we have trouble */
2163 werror (E_LVALUE_REQUIRED, "++");
2167 rOp = newiTempOperand (rvtype, 0);
2173 geniCodeAssign (rOp, rv, 0);
2175 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2176 if (IS_FLOAT (rvtype))
2177 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2179 ic = newiCode ('-', rv, operandFromLit (size));
2181 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2184 geniCodeAssign (op, result, 0);
2190 /*-----------------------------------------------------------------*/
2191 /* geniCodePreDec - generate code for pre decrement */
2192 /*-----------------------------------------------------------------*/
2194 geniCodePreDec (operand * op)
2197 sym_link *optype = operandType (op);
2198 operand *rop = (IS_ITEMP (op) ?
2199 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2201 sym_link *roptype = operandType (rop);
2207 werror (E_LVALUE_REQUIRED, "++");
2212 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2213 if (IS_FLOAT (roptype))
2214 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2216 ic = newiCode ('-', rop, operandFromLit (size));
2217 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2221 return geniCodeAssign (op, result, 0);
2225 /*-----------------------------------------------------------------*/
2226 /* geniCodeBitwise - gen int code for bitWise operators */
2227 /*-----------------------------------------------------------------*/
2229 geniCodeBitwise (operand * left, operand * right,
2230 int oper, sym_link * resType)
2234 left = geniCodeCast (resType, left, TRUE);
2235 right = geniCodeCast (resType, right, TRUE);
2237 ic = newiCode (oper, left, right);
2238 IC_RESULT (ic) = newiTempOperand (resType, 0);
2241 return IC_RESULT (ic);
2244 /*-----------------------------------------------------------------*/
2245 /* geniCodeAddressOf - gens icode for '&' address of operator */
2246 /*-----------------------------------------------------------------*/
2248 geniCodeAddressOf (operand * op)
2252 sym_link *optype = operandType (op);
2253 sym_link *opetype = getSpec (optype);
2255 /* lvalue check already done in decorateType */
2256 /* this must be a lvalue */
2257 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2258 /* werror (E_LVALUE_REQUIRED,"&"); */
2263 p->class = DECLARATOR;
2265 /* set the pointer depending on the storage class */
2266 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2267 DCL_PTR_CONST (p) = port->mem.code_ro;
2269 /* make sure we preserve the const & volatile */
2270 if (IS_CONSTANT (opetype))
2271 DCL_PTR_CONST (p) = 1;
2273 if (IS_VOLATILE (opetype))
2274 DCL_PTR_VOLATILE (p) = 1;
2276 p->next = copyLinkChain (optype);
2278 /* if already a temp */
2281 setOperandType (op, p);
2286 /* other wise make this of the type coming in */
2287 ic = newiCode (ADDRESS_OF, op, NULL);
2288 IC_RESULT (ic) = newiTempOperand (p, 1);
2289 IC_RESULT (ic)->isaddr = 0;
2291 return IC_RESULT (ic);
2293 /*-----------------------------------------------------------------*/
2294 /* setOClass - sets the output class depending on the pointer type */
2295 /*-----------------------------------------------------------------*/
2297 setOClass (sym_link * ptr, sym_link * spec)
2299 switch (DCL_TYPE (ptr))
2302 SPEC_OCLS (spec) = data;
2306 SPEC_OCLS (spec) = generic;
2310 SPEC_OCLS (spec) = xdata;
2314 SPEC_OCLS (spec) = code;
2318 SPEC_OCLS (spec) = idata;
2322 SPEC_OCLS (spec) = xstack;
2326 SPEC_OCLS (spec) = eeprom;
2335 /*-----------------------------------------------------------------*/
2336 /* geniCodeDerefPtr - dereference pointer with '*' */
2337 /*-----------------------------------------------------------------*/
2339 geniCodeDerefPtr (operand * op)
2341 sym_link *rtype, *retype;
2342 sym_link *optype = operandType (op);
2344 /* if this is a pointer then generate the rvalue */
2345 if (IS_PTR (optype))
2347 if (IS_TRUE_SYMOP (op))
2350 op = geniCodeRValue (op, TRUE);
2353 op = geniCodeRValue (op, TRUE);
2356 /* now get rid of the pointer part */
2357 if (lvaluereq && IS_ITEMP (op))
2359 retype = getSpec (rtype = copyLinkChain (optype));
2363 retype = getSpec (rtype = copyLinkChain (optype->next));
2366 /* if this is a pointer then outputclass needs 2b updated */
2367 if (IS_PTR (optype))
2368 setOClass (optype, retype);
2370 op->isGptr = IS_GENPTR (optype);
2372 /* if the pointer was declared as a constant */
2373 /* then we cannot allow assignment to the derefed */
2374 if (IS_PTR_CONST (optype))
2375 SPEC_CONST (retype) = 1;
2377 op->isaddr = (IS_PTR (rtype) ||
2378 IS_STRUCT (rtype) ||
2384 op = geniCodeRValue (op, TRUE);
2386 setOperandType (op, rtype);
2391 /*-----------------------------------------------------------------*/
2392 /* geniCodeUnaryMinus - does a unary minus of the operand */
2393 /*-----------------------------------------------------------------*/
2395 geniCodeUnaryMinus (operand * op)
2398 sym_link *optype = operandType (op);
2400 if (IS_LITERAL (optype))
2401 return operandFromLit (-floatFromVal (op->operand.valOperand));
2403 ic = newiCode (UNARYMINUS, op, NULL);
2404 IC_RESULT (ic) = newiTempOperand (optype, 0);
2406 return IC_RESULT (ic);
2409 /*-----------------------------------------------------------------*/
2410 /* geniCodeLeftShift - gen i code for left shift */
2411 /*-----------------------------------------------------------------*/
2413 geniCodeLeftShift (operand * left, operand * right)
2418 /* Note that we don't use the usual binary conversions for the
2419 * shift operations, in accordance with our ANSI friends.
2421 if (options.ANSIint)
2423 right = usualUnaryConversions (right);
2424 left = usualUnaryConversions (left);
2427 ic = newiCode (LEFT_OP, left, right);
2428 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2430 return IC_RESULT (ic);
2433 /*-----------------------------------------------------------------*/
2434 /* geniCodeRightShift - gen i code for right shift */
2435 /*-----------------------------------------------------------------*/
2437 geniCodeRightShift (operand * left, operand * right)
2442 /* Note that we don't use the usual binary conversions for the
2443 * shift operations, in accordance with our ANSI friends.
2445 if (options.ANSIint)
2447 right = usualUnaryConversions (right);
2448 left = usualUnaryConversions (left);
2451 ic = newiCode (RIGHT_OP, left, right);
2452 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2454 return IC_RESULT (ic);
2457 #if defined(__BORLANDC__) || defined(_MSC_VER)
2458 #define LONG_LONG __int64
2460 #define LONG_LONG long long
2463 /*-----------------------------------------------------------------*/
2464 /* geniCodeLogic- logic code */
2465 /*-----------------------------------------------------------------*/
2467 geniCodeLogic (operand * left, operand * right, int op)
2471 sym_link *rtype = operandType (right);
2472 sym_link *ltype = operandType (left);
2474 /* left is integral type and right is literal then
2475 check if the literal value is within bounds */
2476 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2478 int nbits = bitsForType (ltype);
2479 long v = operandLitValue (right);
2481 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2482 werror (W_CONST_RANGE, " compare operation ");
2485 ctype = usualBinaryConversions (&left, &right);
2487 ic = newiCode (op, left, right);
2488 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2490 /* if comparing anything greater than one byte
2491 and not a '==' || '!=' || '&&' || '||' (these
2493 if (getSize (ctype) > 1 &&
2501 return IC_RESULT (ic);
2504 /*-----------------------------------------------------------------*/
2505 /* geniCodeUnary - for a a generic unary operation */
2506 /*-----------------------------------------------------------------*/
2508 geniCodeUnary (operand * op, int oper)
2510 iCode *ic = newiCode (oper, op, NULL);
2512 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2514 return IC_RESULT (ic);
2517 /*-----------------------------------------------------------------*/
2518 /* geniCodeConditional - geniCode for '?' ':' operation */
2519 /*-----------------------------------------------------------------*/
2521 geniCodeConditional (ast * tree)
2524 symbol *falseLabel = newiTempLabel (NULL);
2525 symbol *exitLabel = newiTempLabel (NULL);
2526 operand *cond = ast2iCode (tree->left);
2527 operand *true, *false, *result;
2529 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2533 true = ast2iCode (tree->right->left);
2535 /* move the value to a new Operand */
2536 result = newiTempOperand (operandType (true), 0);
2537 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2539 /* generate an unconditional goto */
2540 geniCodeGoto (exitLabel);
2542 /* now for the right side */
2543 geniCodeLabel (falseLabel);
2545 false = ast2iCode (tree->right->right);
2546 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2548 /* create the exit label */
2549 geniCodeLabel (exitLabel);
2554 /*-----------------------------------------------------------------*/
2555 /* geniCodeAssign - generate code for assignment */
2556 /*-----------------------------------------------------------------*/
2558 geniCodeAssign (operand * left, operand * right, int nosupdate)
2561 sym_link *ltype = operandType (left);
2562 sym_link *rtype = operandType (right);
2564 if (!left->isaddr && !IS_ITEMP (left))
2566 werror (E_LVALUE_REQUIRED, "assignment");
2570 /* left is integral type and right is literal then
2571 check if the literal value is within bounds */
2572 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2574 int nbits = bitsForType (ltype);
2575 long v = operandLitValue (right);
2577 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2578 werror (W_CONST_RANGE, " = operation");
2581 /* if the left & right type don't exactly match */
2582 /* if pointer set then make sure the check is
2583 done with the type & not the pointer */
2584 /* then cast rights type to left */
2586 /* first check the type for pointer assignement */
2587 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2588 checkType (ltype, rtype) < 0)
2590 if (checkType (ltype->next, rtype) < 0)
2591 right = geniCodeCast (ltype->next, right, TRUE);
2593 else if (checkType (ltype, rtype) < 0)
2594 right = geniCodeCast (ltype, right, TRUE);
2596 /* if left is a true symbol & ! volatile
2597 create an assignment to temporary for
2598 the right & then assign this temporary
2599 to the symbol this is SSA . isn't it simple
2600 and folks have published mountains of paper on it */
2601 if (IS_TRUE_SYMOP (left) &&
2602 !isOperandVolatile (left, FALSE) &&
2603 isOperandGlobal (left))
2607 if (IS_TRUE_SYMOP (right))
2608 sym = OP_SYMBOL (right);
2609 ic = newiCode ('=', NULL, right);
2610 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2611 SPIL_LOC (right) = sym;
2615 ic = newiCode ('=', NULL, right);
2616 IC_RESULT (ic) = left;
2619 /* if left isgptr flag is set then support
2620 routine will be required */
2624 ic->nosupdate = nosupdate;
2628 /*-----------------------------------------------------------------*/
2629 /* geniCodeSEParms - generate code for side effecting fcalls */
2630 /*-----------------------------------------------------------------*/
2632 geniCodeSEParms (ast * parms)
2637 if (parms->type == EX_OP && parms->opval.op == PARAM)
2639 geniCodeSEParms (parms->left);
2640 geniCodeSEParms (parms->right);
2644 /* hack don't like this but too lazy to think of
2646 if (IS_ADDRESS_OF_OP (parms))
2647 parms->left->lvalue = 1;
2649 if (IS_CAST_OP (parms) &&
2650 IS_PTR (parms->ftype) &&
2651 IS_ADDRESS_OF_OP (parms->right))
2652 parms->right->left->lvalue = 1;
2654 parms->opval.oprnd =
2655 geniCodeRValue (ast2iCode (parms), FALSE);
2657 parms->type = EX_OPERAND;
2660 /*-----------------------------------------------------------------*/
2661 /* geniCodeParms - generates parameters */
2662 /*-----------------------------------------------------------------*/
2664 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
2672 /* if this is a param node then do the left & right */
2673 if (parms->type == EX_OP && parms->opval.op == PARAM)
2675 geniCodeParms (parms->left, stack, fetype, func);
2676 geniCodeParms (parms->right, stack, fetype, func);
2680 /* get the parameter value */
2681 if (parms->type == EX_OPERAND)
2682 pval = parms->opval.oprnd;
2685 /* maybe this else should go away ?? */
2686 /* hack don't like this but too lazy to think of
2688 if (IS_ADDRESS_OF_OP (parms))
2689 parms->left->lvalue = 1;
2691 if (IS_CAST_OP (parms) &&
2692 IS_PTR (parms->ftype) &&
2693 IS_ADDRESS_OF_OP (parms->right))
2694 parms->right->left->lvalue = 1;
2696 pval = geniCodeRValue (ast2iCode (parms), FALSE);
2699 /* if register parm then make it a send */
2700 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2701 IS_REGPARM (parms->etype)) && !func->hasVargs)
2703 ic = newiCode (SEND, pval, NULL);
2708 /* now decide whether to push or assign */
2709 if (!(options.stackAuto || IS_RENT (fetype)))
2713 operand *top = operandFromSymbol (parms->argSym);
2714 geniCodeAssign (top, pval, 1);
2718 sym_link *p = operandType (pval);
2720 ic = newiCode (IPUSH, pval, NULL);
2722 /* update the stack adjustment */
2723 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2730 /*-----------------------------------------------------------------*/
2731 /* geniCodeCall - generates temp code for calling */
2732 /*-----------------------------------------------------------------*/
2734 geniCodeCall (operand * left, ast * parms)
2738 sym_link *type, *etype;
2741 /* take care of parameters with side-effecting
2742 function calls in them, this is required to take care
2743 of overlaying function parameters */
2744 geniCodeSEParms (parms);
2746 /* first the parameters */
2747 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
2749 /* now call : if symbol then pcall */
2750 if (IS_ITEMP (left))
2751 ic = newiCode (PCALL, left, NULL);
2753 ic = newiCode (CALL, left, NULL);
2755 IC_ARGS (ic) = left->operand.symOperand->args;
2756 type = copyLinkChain (operandType (left)->next);
2757 etype = getSpec (type);
2758 SPEC_EXTR (etype) = 0;
2759 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2763 /* stack adjustment after call */
2764 left->parmBytes = stack;
2769 /*-----------------------------------------------------------------*/
2770 /* geniCodeReceive - generate intermediate code for "receive" */
2771 /*-----------------------------------------------------------------*/
2773 geniCodeReceive (value * args)
2775 /* for all arguments that are passed in registers */
2779 if (IS_REGPARM (args->etype))
2781 operand *opr = operandFromValue (args);
2783 symbol *sym = OP_SYMBOL (opr);
2786 /* we will use it after all optimizations
2787 and before liveRange calculation */
2788 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2791 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2792 options.stackAuto == 0 &&
2798 opl = newiTempOperand (args->type, 0);
2800 sym->reqv->key = sym->key;
2801 OP_SYMBOL (sym->reqv)->key = sym->key;
2802 OP_SYMBOL (sym->reqv)->isreqv = 1;
2803 OP_SYMBOL (sym->reqv)->islocal = 0;
2804 SPIL_LOC (sym->reqv) = sym;
2808 ic = newiCode (RECEIVE, NULL, NULL);
2809 currFunc->recvSize = getSize (sym->etype);
2810 IC_RESULT (ic) = opr;
2818 /*-----------------------------------------------------------------*/
2819 /* geniCodeFunctionBody - create the function body */
2820 /*-----------------------------------------------------------------*/
2822 geniCodeFunctionBody (ast * tree)
2829 /* reset the auto generation */
2835 func = ast2iCode (tree->left);
2836 fetype = getSpec (operandType (func));
2838 savelineno = lineno;
2839 lineno = OP_SYMBOL (func)->lineDef;
2840 /* create an entry label */
2841 geniCodeLabel (entryLabel);
2842 lineno = savelineno;
2844 /* create a proc icode */
2845 ic = newiCode (FUNCTION, func, NULL);
2846 /* if the function has parmas then */
2847 /* save the parameters information */
2848 ic->argLabel.args = tree->values.args;
2849 ic->lineno = OP_SYMBOL (func)->lineDef;
2853 /* for all parameters that are passed
2854 on registers add a "receive" */
2855 geniCodeReceive (tree->values.args);
2857 /* generate code for the body */
2858 ast2iCode (tree->right);
2860 /* create a label for return */
2861 geniCodeLabel (returnLabel);
2863 /* now generate the end proc */
2864 ic = newiCode (ENDFUNCTION, func, NULL);
2869 /*-----------------------------------------------------------------*/
2870 /* geniCodeReturn - gen icode for 'return' statement */
2871 /*-----------------------------------------------------------------*/
2873 geniCodeReturn (operand * op)
2877 /* if the operand is present force an rvalue */
2879 op = geniCodeRValue (op, FALSE);
2881 ic = newiCode (RETURN, op, NULL);
2885 /*-----------------------------------------------------------------*/
2886 /* geniCodeIfx - generates code for extended if statement */
2887 /*-----------------------------------------------------------------*/
2889 geniCodeIfx (ast * tree)
2892 operand *condition = ast2iCode (tree->left);
2895 /* if condition is null then exit */
2899 condition = geniCodeRValue (condition, FALSE);
2901 cetype = getSpec (operandType (condition));
2902 /* if the condition is a literal */
2903 if (IS_LITERAL (cetype))
2905 if (floatFromVal (condition->operand.valOperand))
2907 if (tree->trueLabel)
2908 geniCodeGoto (tree->trueLabel);
2914 if (tree->falseLabel)
2915 geniCodeGoto (tree->falseLabel);
2922 if (tree->trueLabel)
2924 ic = newiCodeCondition (condition,
2929 if (tree->falseLabel)
2930 geniCodeGoto (tree->falseLabel);
2934 ic = newiCodeCondition (condition,
2941 ast2iCode (tree->right);
2944 /*-----------------------------------------------------------------*/
2945 /* geniCodeJumpTable - tries to create a jump table for switch */
2946 /*-----------------------------------------------------------------*/
2948 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2950 int min = 0, max = 0, t, cnt = 0;
2957 if (!tree || !caseVals)
2960 /* the criteria for creating a jump table is */
2961 /* all integer numbers between the maximum & minimum must */
2962 /* be present , the maximum value should not exceed 255 */
2963 min = max = (int) floatFromVal (vch = caseVals);
2964 sprintf (buffer, "_case_%d_%d",
2965 tree->values.switchVals.swNum,
2967 addSet (&labels, newiTempLabel (buffer));
2969 /* if there is only one case value then no need */
2970 if (!(vch = vch->next))
2975 if (((t = (int) floatFromVal (vch)) - max) != 1)
2977 sprintf (buffer, "_case_%d_%d",
2978 tree->values.switchVals.swNum,
2980 addSet (&labels, newiTempLabel (buffer));
2986 /* if the number of case statements <= 2 then */
2987 /* it is not economical to create the jump table */
2988 /* since two compares are needed for boundary conditions */
2989 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2992 if (tree->values.switchVals.swDefault)
2993 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2995 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2997 falseLabel = newiTempLabel (buffer);
2999 /* so we can create a jumptable */
3000 /* first we rule out the boundary conditions */
3001 /* if only optimization says so */
3002 if (!optimize.noJTabBoundary)
3004 sym_link *cetype = getSpec (operandType (cond));
3005 /* no need to check the lower bound if
3006 the condition is unsigned & minimum value is zero */
3007 if (!(min == 0 && SPEC_USIGN (cetype)))
3009 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3010 ic = newiCodeCondition (boundary, falseLabel, NULL);
3014 /* now for upper bounds */
3015 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3016 ic = newiCodeCondition (boundary, falseLabel, NULL);
3020 /* if the min is not zero then we no make it zero */
3023 cond = geniCodeSubtract (cond, operandFromLit (min));
3024 setOperandType (cond, UCHARTYPE);
3027 /* now create the jumptable */
3028 ic = newiCode (JUMPTABLE, NULL, NULL);
3029 IC_JTCOND (ic) = cond;
3030 IC_JTLABELS (ic) = labels;
3035 /*-----------------------------------------------------------------*/
3036 /* geniCodeSwitch - changes a switch to a if statement */
3037 /*-----------------------------------------------------------------*/
3039 geniCodeSwitch (ast * tree)
3042 operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
3043 value *caseVals = tree->values.switchVals.swVals;
3044 symbol *trueLabel, *falseLabel;
3046 /* if we can make this a jump table */
3047 if (geniCodeJumpTable (cond, caseVals, tree))
3048 goto jumpTable; /* no need for the comparison */
3050 /* for the cases defined do */
3054 operand *compare = geniCodeLogic (cond,
3055 operandFromValue (caseVals),
3058 sprintf (buffer, "_case_%d_%d",
3059 tree->values.switchVals.swNum,
3060 (int) floatFromVal (caseVals));
3061 trueLabel = newiTempLabel (buffer);
3063 ic = newiCodeCondition (compare, trueLabel, NULL);
3065 caseVals = caseVals->next;
3070 /* if default is present then goto break else break */
3071 if (tree->values.switchVals.swDefault)
3072 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3074 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3076 falseLabel = newiTempLabel (buffer);
3077 geniCodeGoto (falseLabel);
3080 ast2iCode (tree->right);
3083 /*-----------------------------------------------------------------*/
3084 /* geniCodeInline - intermediate code for inline assembler */
3085 /*-----------------------------------------------------------------*/
3087 geniCodeInline (ast * tree)
3091 ic = newiCode (INLINEASM, NULL, NULL);
3092 IC_INLINE (ic) = tree->values.inlineasm;
3096 /*-----------------------------------------------------------------*/
3097 /* ast2iCode - creates an icodeList from an ast */
3098 /*-----------------------------------------------------------------*/
3100 ast2iCode (ast * tree)
3102 operand *left = NULL;
3103 operand *right = NULL;
3108 /* set the global variables for filename & line number */
3110 filename = tree->filename;
3112 lineno = tree->lineno;
3114 block = tree->block;
3116 scopeLevel = tree->level;
3118 if (tree->type == EX_VALUE)
3119 return operandFromValue (tree->opval.val);
3121 if (tree->type == EX_LINK)
3122 return operandFromLink (tree->opval.lnk);
3124 /* if we find a nullop */
3125 if (tree->type == EX_OP &&
3126 (tree->opval.op == NULLOP ||
3127 tree->opval.op == BLOCK))
3129 ast2iCode (tree->left);
3130 ast2iCode (tree->right);
3134 /* special cases for not evaluating */
3135 if (tree->opval.op != ':' &&
3136 tree->opval.op != '?' &&
3137 tree->opval.op != CALL &&
3138 tree->opval.op != IFX &&
3139 tree->opval.op != LABEL &&
3140 tree->opval.op != GOTO &&
3141 tree->opval.op != SWITCH &&
3142 tree->opval.op != FUNCTION &&
3143 tree->opval.op != INLINEASM)
3146 if (IS_ASSIGN_OP (tree->opval.op) ||
3147 IS_DEREF_OP (tree) ||
3148 (tree->opval.op == '&' && !tree->right) ||
3149 tree->opval.op == PTR_OP)
3152 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3153 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3155 int olvr = lvaluereq;
3157 left = operandFromAst (tree->left);
3158 lvaluereq = olvr - 1;
3162 left = operandFromAst (tree->left);
3165 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3166 left = geniCodeRValue (left, TRUE);
3170 left = operandFromAst (tree->left);
3172 if (tree->opval.op == INC_OP ||
3173 tree->opval.op == DEC_OP)
3176 right = operandFromAst (tree->right);
3181 right = operandFromAst (tree->right);
3185 /* now depending on the type of operand */
3186 /* this will be a biggy */
3187 switch (tree->opval.op)
3190 case '[': /* array operation */
3192 sym_link *ltype = operandType (left);
3193 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3194 right = geniCodeRValue (right, TRUE);
3197 return geniCodeArray (left, right);
3199 case '.': /* structure dereference */
3200 if (IS_PTR (operandType (left)))
3201 left = geniCodeRValue (left, TRUE);
3203 left = geniCodeRValue (left, FALSE);
3205 return geniCodeStruct (left, right, tree->lvalue);
3207 case PTR_OP: /* structure pointer dereference */
3210 pType = operandType (left);
3211 left = geniCodeRValue (left, TRUE);
3213 setOClass (pType, getSpec (operandType (left)));
3216 return geniCodeStruct (left, right, tree->lvalue);
3218 case INC_OP: /* increment operator */
3220 return geniCodePostInc (left);
3222 return geniCodePreInc (right);
3224 case DEC_OP: /* decrement operator */
3226 return geniCodePostDec (left);
3228 return geniCodePreDec (right);
3230 case '&': /* bitwise and or address of operator */
3232 { /* this is a bitwise operator */
3233 left = geniCodeRValue (left, FALSE);
3234 right = geniCodeRValue (right, FALSE);
3235 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3238 return geniCodeAddressOf (left);
3240 case '|': /* bitwise or & xor */
3242 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3243 geniCodeRValue (right, FALSE),
3248 return geniCodeDivision (geniCodeRValue (left, FALSE),
3249 geniCodeRValue (right, FALSE));
3252 return geniCodeModulus (geniCodeRValue (left, FALSE),
3253 geniCodeRValue (right, FALSE));
3256 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3257 geniCodeRValue (right, FALSE), FALSE);
3259 return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
3263 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3264 geniCodeRValue (right, FALSE));
3266 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3270 return geniCodeAdd (geniCodeRValue (left, FALSE),
3271 geniCodeRValue (right, FALSE));
3273 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3276 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3277 geniCodeRValue (right, FALSE));
3280 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3281 geniCodeRValue (right, FALSE));
3283 return geniCodeCast (operandType (left),
3284 geniCodeRValue (right, FALSE), FALSE);
3290 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3294 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3295 setOperandType (op, UCHARTYPE);
3306 return geniCodeLogic (geniCodeRValue (left, FALSE),
3307 geniCodeRValue (right, FALSE),
3310 return geniCodeConditional (tree);
3313 return operandFromLit (getSize (tree->right->ftype));
3317 sym_link *rtype = operandType (right);
3318 sym_link *ltype = operandType (left);
3319 if (IS_PTR (rtype) && IS_ITEMP (right)
3320 && right->isaddr && checkType (rtype->next, ltype) == 1)
3321 right = geniCodeRValue (right, TRUE);
3323 right = geniCodeRValue (right, FALSE);
3325 geniCodeAssign (left, right, 0);
3330 geniCodeAssign (left,
3331 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3333 geniCodeRValue (right, FALSE), FALSE), 0);
3337 geniCodeAssign (left,
3338 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3340 geniCodeRValue (right, FALSE)), 0);
3343 geniCodeAssign (left,
3344 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3346 geniCodeRValue (right, FALSE)), 0);
3349 sym_link *rtype = operandType (right);
3350 sym_link *ltype = operandType (left);
3351 if (IS_PTR (rtype) && IS_ITEMP (right)
3352 && right->isaddr && checkType (rtype->next, ltype) == 1)
3353 right = geniCodeRValue (right, TRUE);
3355 right = geniCodeRValue (right, FALSE);
3358 return geniCodeAssign (left,
3359 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3365 sym_link *rtype = operandType (right);
3366 sym_link *ltype = operandType (left);
3367 if (IS_PTR (rtype) && IS_ITEMP (right)
3368 && right->isaddr && checkType (rtype->next, ltype) == 1)
3370 right = geniCodeRValue (right, TRUE);
3374 right = geniCodeRValue (right, FALSE);
3377 geniCodeAssign (left,
3378 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3384 geniCodeAssign (left,
3385 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3387 geniCodeRValue (right, FALSE)), 0);
3390 geniCodeAssign (left,
3391 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3393 geniCodeRValue (right, FALSE)), 0);
3396 geniCodeAssign (left,
3397 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3399 geniCodeRValue (right, FALSE),
3401 operandType (left)), 0);
3404 geniCodeAssign (left,
3405 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3407 geniCodeRValue (right, FALSE),
3409 operandType (left)), 0);
3412 geniCodeAssign (left,
3413 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3415 geniCodeRValue (right, FALSE),
3417 operandType (left)), 0);
3419 return geniCodeRValue (right, FALSE);
3422 return geniCodeCall (ast2iCode (tree->left),
3425 geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
3426 return ast2iCode (tree->right);
3429 geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
3430 return ast2iCode (tree->right);
3433 geniCodeFunctionBody (tree);
3437 geniCodeReturn (right);
3445 geniCodeSwitch (tree);
3449 geniCodeInline (tree);
3456 /*-----------------------------------------------------------------*/
3457 /* reverseICChain - gets from the list and creates a linkedlist */
3458 /*-----------------------------------------------------------------*/
3465 while ((loop = getSet (&iCodeChain)))
3477 /*-----------------------------------------------------------------*/
3478 /* iCodeFromAst - given an ast will convert it to iCode */
3479 /*-----------------------------------------------------------------*/
3481 iCodeFromAst (ast * tree)
3483 returnLabel = newiTempLabel ("_return");
3484 entryLabel = newiTempLabel ("_entry");
3486 return reverseiCChain ();