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,
1659 /* if they are both literal then we know the result */
1660 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1661 return operandFromValue (valMult (left->operand.valOperand,
1662 right->operand.valOperand));
1665 //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size
1666 if ((ptrSizeCalculation) && (1 == getSize (rtype)) &&
1667 (1 == getSize (ltype)))
1669 saveOption = options.ANSIint;
1670 options.ANSIint = 0;
1671 resType = usualBinaryConversions (&left, &right);
1672 ltype = operandType (left);
1673 rtype = operandType (right);
1674 SPEC_SHORT (getSpec (resType)) = 0;
1675 options.ANSIint = saveOption;
1678 resType = usualBinaryConversions (&left, &right);
1679 /* if (IS_DS390_PORT) { */
1680 /* jwk char*char=int
1681 Now be can use the 16bit result of "mul a,b" instead of explicit
1682 casts and support function calls as with --ansiint
1684 /* if ((IS_CHAR(letype) || IS_SHORT(letype)) && */
1685 /* (IS_CHAR(retype) || IS_SHORT(retype))) { */
1687 SPEC_NOUN(getSpec(resType))=V_INT;
1688 SPEC_SHORT(getSpec(resType))=0;
1693 /* if the right is a literal & power of 2 */
1694 /* then make it a left shift */
1695 /*If we are computing ptr size then normal multiplication */
1696 /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
1697 /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
1698 if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
1699 !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
1700 (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
1702 if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)))
1704 /* LEFT_OP need same size for left and result, */
1705 left = geniCodeCast (resType, left, TRUE);
1706 ltype = operandType (left);
1708 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1712 ic = newiCode ('*', left, right); /* normal multiplication */
1713 /* if the size left or right > 1 then support routine */
1714 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1718 IC_RESULT (ic) = newiTempOperand (resType, 1);
1721 return IC_RESULT (ic);
1724 /*-----------------------------------------------------------------*/
1725 /* geniCodeDivision - gen intermediate code for division */
1726 /*-----------------------------------------------------------------*/
1728 geniCodeDivision (operand * left, operand * right)
1733 sym_link *rtype = operandType (right);
1734 sym_link *retype = getSpec (rtype);
1735 sym_link *ltype = operandType (left);
1736 sym_link *letype = getSpec (ltype);
1738 resType = usualBinaryConversions (&left, &right);
1740 /* if the right is a literal & power of 2 */
1741 /* then make it a right shift */
1742 if (IS_LITERAL (retype) &&
1743 !IS_FLOAT (letype) &&
1744 (p2 = powof2 ((unsigned long)
1745 floatFromVal (right->operand.valOperand))))
1746 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1749 ic = newiCode ('/', left, right); /* normal division */
1750 /* if the size left or right > 1 then support routine */
1751 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1754 IC_RESULT (ic) = newiTempOperand (resType, 0);
1757 return IC_RESULT (ic);
1759 /*-----------------------------------------------------------------*/
1760 /* geniCodeModulus - gen intermediate code for modulus */
1761 /*-----------------------------------------------------------------*/
1763 geniCodeModulus (operand * left, operand * right)
1769 /* if they are both literal then we know the result */
1770 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1771 return operandFromValue (valMod (left->operand.valOperand,
1772 right->operand.valOperand));
1774 resType = usualBinaryConversions (&left, &right);
1776 /* now they are the same size */
1777 ic = newiCode ('%', left, right);
1779 /* if the size left or right > 1 then support routine */
1780 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1782 IC_RESULT (ic) = newiTempOperand (resType, 0);
1785 return IC_RESULT (ic);
1788 /*-----------------------------------------------------------------*/
1789 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1790 /*-----------------------------------------------------------------*/
1792 geniCodePtrPtrSubtract (operand * left, operand * right)
1798 /* if they are both literals then */
1799 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1801 result = operandFromValue (valMinus (left->operand.valOperand,
1802 right->operand.valOperand));
1806 ic = newiCode ('-', left, right);
1808 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1812 return geniCodeDivision (result,
1813 operandFromLit (getSize (ltype->next)));
1816 /*-----------------------------------------------------------------*/
1817 /* geniCodeSubtract - generates code for subtraction */
1818 /*-----------------------------------------------------------------*/
1820 geniCodeSubtract (operand * left, operand * right)
1827 /* if they both pointers then */
1828 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1829 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1830 return geniCodePtrPtrSubtract (left, right);
1832 /* if they are both literal then we know the result */
1833 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1834 && left->isLiteral && right->isLiteral)
1835 return operandFromValue (valMinus (left->operand.valOperand,
1836 right->operand.valOperand));
1838 /* if left is an array or pointer */
1839 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1841 isarray = left->isaddr;
1842 right = geniCodeMultiply (right,
1843 operandFromLit (getSize (ltype->next)), TRUE, FALSE);
1844 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1847 { /* make them the same size */
1848 resType = usualBinaryConversions (&left, &right);
1851 ic = newiCode ('-', left, right);
1853 IC_RESULT (ic) = newiTempOperand (resType, 1);
1854 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1856 /* if left or right is a float */
1857 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1861 return IC_RESULT (ic);
1864 /*-----------------------------------------------------------------*/
1865 /* geniCodeAdd - generates iCode for addition */
1866 /*-----------------------------------------------------------------*/
1868 geniCodeAdd (operand * left, operand * right)
1876 /* if left is an array then array access */
1877 if (IS_ARRAY (ltype))
1878 return geniCodeArray (left, right);
1880 /* if the right side is LITERAL zero */
1881 /* return the left side */
1882 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1885 /* if left is literal zero return right */
1886 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1889 /* if left is an array or pointer then size */
1893 isarray = left->isaddr;
1895 operandFromLit (getSize (ltype->next));
1897 right = geniCodeMultiply (right, size, (getSize (ltype) != 1),FALSE);
1899 resType = copyLinkChain (ltype);
1902 { /* make them the same size */
1903 resType = usualBinaryConversions (&left, &right);
1906 /* if they are both literals then we know */
1907 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1908 && left->isLiteral && right->isLiteral)
1909 return operandFromValue (valPlus (valFromType (letype),
1910 valFromType (retype)));
1912 ic = newiCode ('+', left, right);
1914 IC_RESULT (ic) = newiTempOperand (resType, 1);
1915 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1917 /* if left or right is a float then support
1919 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1924 return IC_RESULT (ic);
1928 /*-----------------------------------------------------------------*/
1929 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1930 /*-----------------------------------------------------------------*/
1932 aggrToPtr (sym_link * type, bool force)
1938 if (IS_PTR (type) && !force)
1941 etype = getSpec (type);
1945 /* if the output class is generic */
1946 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1947 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1949 /* if the variable was declared a constant */
1950 /* then the pointer points to a constant */
1951 if (IS_CONSTANT (etype))
1952 DCL_PTR_CONST (ptype) = 1;
1954 /* the variable was volatile then pointer to volatile */
1955 if (IS_VOLATILE (etype))
1956 DCL_PTR_VOLATILE (ptype) = 1;
1960 /*-----------------------------------------------------------------*/
1961 /* geniCodeArray2Ptr - array to pointer */
1962 /*-----------------------------------------------------------------*/
1964 geniCodeArray2Ptr (operand * op)
1966 sym_link *optype = operandType (op);
1967 sym_link *opetype = getSpec (optype);
1969 /* set the pointer depending on the storage class */
1970 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1971 DCL_PTR_CONST (optype) = port->mem.code_ro;
1974 /* if the variable was declared a constant */
1975 /* then the pointer points to a constant */
1976 if (IS_CONSTANT (opetype))
1977 DCL_PTR_CONST (optype) = 1;
1979 /* the variable was volatile then pointer to volatile */
1980 if (IS_VOLATILE (opetype))
1981 DCL_PTR_VOLATILE (optype) = 1;
1987 /*-----------------------------------------------------------------*/
1988 /* geniCodeArray - array access */
1989 /*-----------------------------------------------------------------*/
1991 geniCodeArray (operand * left, operand * right)
1994 sym_link *ltype = operandType (left);
1998 if (IS_PTR (ltype->next) && left->isaddr)
2000 left = geniCodeRValue (left, FALSE);
2002 return geniCodeDerefPtr (geniCodeAdd (left, right));
2006 right = geniCodeMultiply (right,
2007 operandFromLit (getSize (ltype->next)), TRUE,FALSE);
2009 /* we can check for limits here */
2010 if (isOperandLiteral (right) &&
2013 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2015 werror (E_ARRAY_BOUND);
2016 right = operandFromLit (0);
2019 ic = newiCode ('+', left, right);
2021 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2022 !IS_AGGREGATE (ltype->next) &&
2023 !IS_PTR (ltype->next))
2024 ? ltype : ltype->next), 0);
2026 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2028 return IC_RESULT (ic);
2031 /*-----------------------------------------------------------------*/
2032 /* geniCodeStruct - generates intermediate code for structres */
2033 /*-----------------------------------------------------------------*/
2035 geniCodeStruct (operand * left, operand * right, bool islval)
2038 sym_link *type = operandType (left);
2039 sym_link *etype = getSpec (type);
2041 symbol *element = getStructElement (SPEC_STRUCT (etype),
2042 right->operand.symOperand);
2044 /* add the offset */
2045 ic = newiCode ('+', left, operandFromLit (element->offset));
2047 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2049 /* preserve the storage & output class of the struct */
2050 /* as well as the volatile attribute */
2051 retype = getSpec (operandType (IC_RESULT (ic)));
2052 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2053 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2054 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2056 if (IS_PTR (element->type))
2057 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2059 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2063 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2066 /*-----------------------------------------------------------------*/
2067 /* geniCodePostInc - generate int code for Post increment */
2068 /*-----------------------------------------------------------------*/
2070 geniCodePostInc (operand * op)
2074 sym_link *optype = operandType (op);
2076 operand *rv = (IS_ITEMP (op) ?
2077 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2079 sym_link *rvtype = operandType (rv);
2082 /* if this is not an address we have trouble */
2085 werror (E_LVALUE_REQUIRED, "++");
2089 rOp = newiTempOperand (rvtype, 0);
2095 geniCodeAssign (rOp, rv, 0);
2097 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2098 if (IS_FLOAT (rvtype))
2099 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2101 ic = newiCode ('+', rv, operandFromLit (size));
2103 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2106 geniCodeAssign (op, result, 0);
2112 /*-----------------------------------------------------------------*/
2113 /* geniCodePreInc - generate code for preIncrement */
2114 /*-----------------------------------------------------------------*/
2116 geniCodePreInc (operand * op)
2119 sym_link *optype = operandType (op);
2120 operand *rop = (IS_ITEMP (op) ?
2121 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2123 sym_link *roptype = operandType (rop);
2129 werror (E_LVALUE_REQUIRED, "++");
2134 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2135 if (IS_FLOAT (roptype))
2136 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2138 ic = newiCode ('+', rop, operandFromLit (size));
2139 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2143 return geniCodeAssign (op, result, 0);
2146 /*-----------------------------------------------------------------*/
2147 /* geniCodePostDec - generates code for Post decrement */
2148 /*-----------------------------------------------------------------*/
2150 geniCodePostDec (operand * op)
2154 sym_link *optype = operandType (op);
2156 operand *rv = (IS_ITEMP (op) ?
2157 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2159 sym_link *rvtype = operandType (rv);
2162 /* if this is not an address we have trouble */
2165 werror (E_LVALUE_REQUIRED, "++");
2169 rOp = newiTempOperand (rvtype, 0);
2175 geniCodeAssign (rOp, rv, 0);
2177 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2178 if (IS_FLOAT (rvtype))
2179 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2181 ic = newiCode ('-', rv, operandFromLit (size));
2183 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2186 geniCodeAssign (op, result, 0);
2192 /*-----------------------------------------------------------------*/
2193 /* geniCodePreDec - generate code for pre decrement */
2194 /*-----------------------------------------------------------------*/
2196 geniCodePreDec (operand * op)
2199 sym_link *optype = operandType (op);
2200 operand *rop = (IS_ITEMP (op) ?
2201 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2203 sym_link *roptype = operandType (rop);
2209 werror (E_LVALUE_REQUIRED, "++");
2214 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2215 if (IS_FLOAT (roptype))
2216 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2218 ic = newiCode ('-', rop, operandFromLit (size));
2219 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2223 return geniCodeAssign (op, result, 0);
2227 /*-----------------------------------------------------------------*/
2228 /* geniCodeBitwise - gen int code for bitWise operators */
2229 /*-----------------------------------------------------------------*/
2231 geniCodeBitwise (operand * left, operand * right,
2232 int oper, sym_link * resType)
2236 left = geniCodeCast (resType, left, TRUE);
2237 right = geniCodeCast (resType, right, TRUE);
2239 ic = newiCode (oper, left, right);
2240 IC_RESULT (ic) = newiTempOperand (resType, 0);
2243 return IC_RESULT (ic);
2246 /*-----------------------------------------------------------------*/
2247 /* geniCodeAddressOf - gens icode for '&' address of operator */
2248 /*-----------------------------------------------------------------*/
2250 geniCodeAddressOf (operand * op)
2254 sym_link *optype = operandType (op);
2255 sym_link *opetype = getSpec (optype);
2257 /* lvalue check already done in decorateType */
2258 /* this must be a lvalue */
2259 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2260 /* werror (E_LVALUE_REQUIRED,"&"); */
2265 p->class = DECLARATOR;
2267 /* set the pointer depending on the storage class */
2268 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2269 DCL_PTR_CONST (p) = port->mem.code_ro;
2271 /* make sure we preserve the const & volatile */
2272 if (IS_CONSTANT (opetype))
2273 DCL_PTR_CONST (p) = 1;
2275 if (IS_VOLATILE (opetype))
2276 DCL_PTR_VOLATILE (p) = 1;
2278 p->next = copyLinkChain (optype);
2280 /* if already a temp */
2283 setOperandType (op, p);
2288 /* other wise make this of the type coming in */
2289 ic = newiCode (ADDRESS_OF, op, NULL);
2290 IC_RESULT (ic) = newiTempOperand (p, 1);
2291 IC_RESULT (ic)->isaddr = 0;
2293 return IC_RESULT (ic);
2295 /*-----------------------------------------------------------------*/
2296 /* setOClass - sets the output class depending on the pointer type */
2297 /*-----------------------------------------------------------------*/
2299 setOClass (sym_link * ptr, sym_link * spec)
2301 switch (DCL_TYPE (ptr))
2304 SPEC_OCLS (spec) = data;
2308 SPEC_OCLS (spec) = generic;
2312 SPEC_OCLS (spec) = xdata;
2316 SPEC_OCLS (spec) = code;
2320 SPEC_OCLS (spec) = idata;
2324 SPEC_OCLS (spec) = xstack;
2328 SPEC_OCLS (spec) = eeprom;
2337 /*-----------------------------------------------------------------*/
2338 /* geniCodeDerefPtr - dereference pointer with '*' */
2339 /*-----------------------------------------------------------------*/
2341 geniCodeDerefPtr (operand * op)
2343 sym_link *rtype, *retype;
2344 sym_link *optype = operandType (op);
2346 /* if this is a pointer then generate the rvalue */
2347 if (IS_PTR (optype))
2349 if (IS_TRUE_SYMOP (op))
2352 op = geniCodeRValue (op, TRUE);
2355 op = geniCodeRValue (op, TRUE);
2358 /* now get rid of the pointer part */
2359 if (lvaluereq && IS_ITEMP (op))
2361 retype = getSpec (rtype = copyLinkChain (optype));
2365 retype = getSpec (rtype = copyLinkChain (optype->next));
2368 /* if this is a pointer then outputclass needs 2b updated */
2369 if (IS_PTR (optype))
2370 setOClass (optype, retype);
2372 op->isGptr = IS_GENPTR (optype);
2374 /* if the pointer was declared as a constant */
2375 /* then we cannot allow assignment to the derefed */
2376 if (IS_PTR_CONST (optype))
2377 SPEC_CONST (retype) = 1;
2379 op->isaddr = (IS_PTR (rtype) ||
2380 IS_STRUCT (rtype) ||
2386 op = geniCodeRValue (op, TRUE);
2388 setOperandType (op, rtype);
2393 /*-----------------------------------------------------------------*/
2394 /* geniCodeUnaryMinus - does a unary minus of the operand */
2395 /*-----------------------------------------------------------------*/
2397 geniCodeUnaryMinus (operand * op)
2400 sym_link *optype = operandType (op);
2402 if (IS_LITERAL (optype))
2403 return operandFromLit (-floatFromVal (op->operand.valOperand));
2405 ic = newiCode (UNARYMINUS, op, NULL);
2406 IC_RESULT (ic) = newiTempOperand (optype, 0);
2408 return IC_RESULT (ic);
2411 /*-----------------------------------------------------------------*/
2412 /* geniCodeLeftShift - gen i code for left shift */
2413 /*-----------------------------------------------------------------*/
2415 geniCodeLeftShift (operand * left, operand * right)
2420 /* Note that we don't use the usual binary conversions for the
2421 * shift operations, in accordance with our ANSI friends.
2423 if (options.ANSIint)
2425 right = usualUnaryConversions (right);
2426 left = usualUnaryConversions (left);
2429 ic = newiCode (LEFT_OP, left, right);
2430 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2432 return IC_RESULT (ic);
2435 /*-----------------------------------------------------------------*/
2436 /* geniCodeRightShift - gen i code for right shift */
2437 /*-----------------------------------------------------------------*/
2439 geniCodeRightShift (operand * left, operand * right)
2444 /* Note that we don't use the usual binary conversions for the
2445 * shift operations, in accordance with our ANSI friends.
2447 if (options.ANSIint)
2449 right = usualUnaryConversions (right);
2450 left = usualUnaryConversions (left);
2453 ic = newiCode (RIGHT_OP, left, right);
2454 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2456 return IC_RESULT (ic);
2459 #if defined(__BORLANDC__) || defined(_MSC_VER)
2460 #define LONG_LONG __int64
2462 #define LONG_LONG long long
2465 /*-----------------------------------------------------------------*/
2466 /* geniCodeLogic- logic code */
2467 /*-----------------------------------------------------------------*/
2469 geniCodeLogic (operand * left, operand * right, int op)
2473 sym_link *rtype = operandType (right);
2474 sym_link *ltype = operandType (left);
2476 /* left is integral type and right is literal then
2477 check if the literal value is within bounds */
2478 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2480 int nbits = bitsForType (ltype);
2481 long v = operandLitValue (right);
2483 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2484 werror (W_CONST_RANGE, " compare operation ");
2487 ctype = usualBinaryConversions (&left, &right);
2489 ic = newiCode (op, left, right);
2490 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2492 /* if comparing anything greater than one byte
2493 and not a '==' || '!=' || '&&' || '||' (these
2495 if (getSize (ctype) > 1 &&
2503 return IC_RESULT (ic);
2506 /*-----------------------------------------------------------------*/
2507 /* geniCodeUnary - for a a generic unary operation */
2508 /*-----------------------------------------------------------------*/
2510 geniCodeUnary (operand * op, int oper)
2512 iCode *ic = newiCode (oper, op, NULL);
2514 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2516 return IC_RESULT (ic);
2519 /*-----------------------------------------------------------------*/
2520 /* geniCodeConditional - geniCode for '?' ':' operation */
2521 /*-----------------------------------------------------------------*/
2523 geniCodeConditional (ast * tree)
2526 symbol *falseLabel = newiTempLabel (NULL);
2527 symbol *exitLabel = newiTempLabel (NULL);
2528 operand *cond = ast2iCode (tree->left);
2529 operand *true, *false, *result;
2531 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2535 true = ast2iCode (tree->right->left);
2537 /* move the value to a new Operand */
2538 result = newiTempOperand (operandType (true), 0);
2539 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2541 /* generate an unconditional goto */
2542 geniCodeGoto (exitLabel);
2544 /* now for the right side */
2545 geniCodeLabel (falseLabel);
2547 false = ast2iCode (tree->right->right);
2548 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2550 /* create the exit label */
2551 geniCodeLabel (exitLabel);
2556 /*-----------------------------------------------------------------*/
2557 /* geniCodeAssign - generate code for assignment */
2558 /*-----------------------------------------------------------------*/
2560 geniCodeAssign (operand * left, operand * right, int nosupdate)
2563 sym_link *ltype = operandType (left);
2564 sym_link *rtype = operandType (right);
2566 if (!left->isaddr && !IS_ITEMP (left))
2568 werror (E_LVALUE_REQUIRED, "assignment");
2572 /* left is integral type and right is literal then
2573 check if the literal value is within bounds */
2574 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2576 int nbits = bitsForType (ltype);
2577 long v = operandLitValue (right);
2579 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2580 werror (W_CONST_RANGE, " = operation");
2583 /* if the left & right type don't exactly match */
2584 /* if pointer set then make sure the check is
2585 done with the type & not the pointer */
2586 /* then cast rights type to left */
2588 /* first check the type for pointer assignement */
2589 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2590 checkType (ltype, rtype) < 0)
2592 if (checkType (ltype->next, rtype) < 0)
2593 right = geniCodeCast (ltype->next, right, TRUE);
2595 else if (checkType (ltype, rtype) < 0)
2596 right = geniCodeCast (ltype, right, TRUE);
2598 /* if left is a true symbol & ! volatile
2599 create an assignment to temporary for
2600 the right & then assign this temporary
2601 to the symbol this is SSA . isn't it simple
2602 and folks have published mountains of paper on it */
2603 if (IS_TRUE_SYMOP (left) &&
2604 !isOperandVolatile (left, FALSE) &&
2605 isOperandGlobal (left))
2609 if (IS_TRUE_SYMOP (right))
2610 sym = OP_SYMBOL (right);
2611 ic = newiCode ('=', NULL, right);
2612 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2613 SPIL_LOC (right) = sym;
2617 ic = newiCode ('=', NULL, right);
2618 IC_RESULT (ic) = left;
2621 /* if left isgptr flag is set then support
2622 routine will be required */
2626 ic->nosupdate = nosupdate;
2630 /*-----------------------------------------------------------------*/
2631 /* geniCodeSEParms - generate code for side effecting fcalls */
2632 /*-----------------------------------------------------------------*/
2634 geniCodeSEParms (ast * parms)
2639 if (parms->type == EX_OP && parms->opval.op == PARAM)
2641 geniCodeSEParms (parms->left);
2642 geniCodeSEParms (parms->right);
2646 /* hack don't like this but too lazy to think of
2648 if (IS_ADDRESS_OF_OP (parms))
2649 parms->left->lvalue = 1;
2651 if (IS_CAST_OP (parms) &&
2652 IS_PTR (parms->ftype) &&
2653 IS_ADDRESS_OF_OP (parms->right))
2654 parms->right->left->lvalue = 1;
2656 parms->opval.oprnd =
2657 geniCodeRValue (ast2iCode (parms), FALSE);
2659 parms->type = EX_OPERAND;
2662 /*-----------------------------------------------------------------*/
2663 /* geniCodeParms - generates parameters */
2664 /*-----------------------------------------------------------------*/
2666 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
2674 /* if this is a param node then do the left & right */
2675 if (parms->type == EX_OP && parms->opval.op == PARAM)
2677 geniCodeParms (parms->left, stack, fetype, func);
2678 geniCodeParms (parms->right, stack, fetype, func);
2682 /* get the parameter value */
2683 if (parms->type == EX_OPERAND)
2684 pval = parms->opval.oprnd;
2687 /* maybe this else should go away ?? */
2688 /* hack don't like this but too lazy to think of
2690 if (IS_ADDRESS_OF_OP (parms))
2691 parms->left->lvalue = 1;
2693 if (IS_CAST_OP (parms) &&
2694 IS_PTR (parms->ftype) &&
2695 IS_ADDRESS_OF_OP (parms->right))
2696 parms->right->left->lvalue = 1;
2698 pval = geniCodeRValue (ast2iCode (parms), FALSE);
2701 /* if register parm then make it a send */
2702 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2703 IS_REGPARM (parms->etype)) && !func->hasVargs)
2705 ic = newiCode (SEND, pval, NULL);
2710 /* now decide whether to push or assign */
2711 if (!(options.stackAuto || IS_RENT (fetype)))
2715 operand *top = operandFromSymbol (parms->argSym);
2716 geniCodeAssign (top, pval, 1);
2720 sym_link *p = operandType (pval);
2722 ic = newiCode (IPUSH, pval, NULL);
2724 /* update the stack adjustment */
2725 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2732 /*-----------------------------------------------------------------*/
2733 /* geniCodeCall - generates temp code for calling */
2734 /*-----------------------------------------------------------------*/
2736 geniCodeCall (operand * left, ast * parms)
2740 sym_link *type, *etype;
2743 /* take care of parameters with side-effecting
2744 function calls in them, this is required to take care
2745 of overlaying function parameters */
2746 geniCodeSEParms (parms);
2748 /* first the parameters */
2749 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
2751 /* now call : if symbol then pcall */
2752 if (IS_ITEMP (left))
2753 ic = newiCode (PCALL, left, NULL);
2755 ic = newiCode (CALL, left, NULL);
2757 IC_ARGS (ic) = left->operand.symOperand->args;
2758 type = copyLinkChain (operandType (left)->next);
2759 etype = getSpec (type);
2760 SPEC_EXTR (etype) = 0;
2761 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2765 /* stack adjustment after call */
2766 left->parmBytes = stack;
2771 /*-----------------------------------------------------------------*/
2772 /* geniCodeReceive - generate intermediate code for "receive" */
2773 /*-----------------------------------------------------------------*/
2775 geniCodeReceive (value * args)
2777 /* for all arguments that are passed in registers */
2781 if (IS_REGPARM (args->etype))
2783 operand *opr = operandFromValue (args);
2785 symbol *sym = OP_SYMBOL (opr);
2788 /* we will use it after all optimizations
2789 and before liveRange calculation */
2790 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2793 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2794 options.stackAuto == 0 &&
2800 opl = newiTempOperand (args->type, 0);
2802 sym->reqv->key = sym->key;
2803 OP_SYMBOL (sym->reqv)->key = sym->key;
2804 OP_SYMBOL (sym->reqv)->isreqv = 1;
2805 OP_SYMBOL (sym->reqv)->islocal = 0;
2806 SPIL_LOC (sym->reqv) = sym;
2810 ic = newiCode (RECEIVE, NULL, NULL);
2811 currFunc->recvSize = getSize (sym->etype);
2812 IC_RESULT (ic) = opr;
2820 /*-----------------------------------------------------------------*/
2821 /* geniCodeFunctionBody - create the function body */
2822 /*-----------------------------------------------------------------*/
2824 geniCodeFunctionBody (ast * tree)
2831 /* reset the auto generation */
2837 func = ast2iCode (tree->left);
2838 fetype = getSpec (operandType (func));
2840 savelineno = lineno;
2841 lineno = OP_SYMBOL (func)->lineDef;
2842 /* create an entry label */
2843 geniCodeLabel (entryLabel);
2844 lineno = savelineno;
2846 /* create a proc icode */
2847 ic = newiCode (FUNCTION, func, NULL);
2848 /* if the function has parmas then */
2849 /* save the parameters information */
2850 ic->argLabel.args = tree->values.args;
2851 ic->lineno = OP_SYMBOL (func)->lineDef;
2855 /* for all parameters that are passed
2856 on registers add a "receive" */
2857 geniCodeReceive (tree->values.args);
2859 /* generate code for the body */
2860 ast2iCode (tree->right);
2862 /* create a label for return */
2863 geniCodeLabel (returnLabel);
2865 /* now generate the end proc */
2866 ic = newiCode (ENDFUNCTION, func, NULL);
2871 /*-----------------------------------------------------------------*/
2872 /* geniCodeReturn - gen icode for 'return' statement */
2873 /*-----------------------------------------------------------------*/
2875 geniCodeReturn (operand * op)
2879 /* if the operand is present force an rvalue */
2881 op = geniCodeRValue (op, FALSE);
2883 ic = newiCode (RETURN, op, NULL);
2887 /*-----------------------------------------------------------------*/
2888 /* geniCodeIfx - generates code for extended if statement */
2889 /*-----------------------------------------------------------------*/
2891 geniCodeIfx (ast * tree)
2894 operand *condition = ast2iCode (tree->left);
2897 /* if condition is null then exit */
2901 condition = geniCodeRValue (condition, FALSE);
2903 cetype = getSpec (operandType (condition));
2904 /* if the condition is a literal */
2905 if (IS_LITERAL (cetype))
2907 if (floatFromVal (condition->operand.valOperand))
2909 if (tree->trueLabel)
2910 geniCodeGoto (tree->trueLabel);
2916 if (tree->falseLabel)
2917 geniCodeGoto (tree->falseLabel);
2924 if (tree->trueLabel)
2926 ic = newiCodeCondition (condition,
2931 if (tree->falseLabel)
2932 geniCodeGoto (tree->falseLabel);
2936 ic = newiCodeCondition (condition,
2943 ast2iCode (tree->right);
2946 /*-----------------------------------------------------------------*/
2947 /* geniCodeJumpTable - tries to create a jump table for switch */
2948 /*-----------------------------------------------------------------*/
2950 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2952 int min = 0, max = 0, t, cnt = 0;
2959 if (!tree || !caseVals)
2962 /* the criteria for creating a jump table is */
2963 /* all integer numbers between the maximum & minimum must */
2964 /* be present , the maximum value should not exceed 255 */
2965 min = max = (int) floatFromVal (vch = caseVals);
2966 sprintf (buffer, "_case_%d_%d",
2967 tree->values.switchVals.swNum,
2969 addSet (&labels, newiTempLabel (buffer));
2971 /* if there is only one case value then no need */
2972 if (!(vch = vch->next))
2977 if (((t = (int) floatFromVal (vch)) - max) != 1)
2979 sprintf (buffer, "_case_%d_%d",
2980 tree->values.switchVals.swNum,
2982 addSet (&labels, newiTempLabel (buffer));
2988 /* if the number of case statements <= 2 then */
2989 /* it is not economical to create the jump table */
2990 /* since two compares are needed for boundary conditions */
2991 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2994 if (tree->values.switchVals.swDefault)
2995 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2997 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2999 falseLabel = newiTempLabel (buffer);
3001 /* so we can create a jumptable */
3002 /* first we rule out the boundary conditions */
3003 /* if only optimization says so */
3004 if (!optimize.noJTabBoundary)
3006 sym_link *cetype = getSpec (operandType (cond));
3007 /* no need to check the lower bound if
3008 the condition is unsigned & minimum value is zero */
3009 if (!(min == 0 && SPEC_USIGN (cetype)))
3011 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3012 ic = newiCodeCondition (boundary, falseLabel, NULL);
3016 /* now for upper bounds */
3017 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3018 ic = newiCodeCondition (boundary, falseLabel, NULL);
3022 /* if the min is not zero then we no make it zero */
3025 cond = geniCodeSubtract (cond, operandFromLit (min));
3026 setOperandType (cond, UCHARTYPE);
3029 /* now create the jumptable */
3030 ic = newiCode (JUMPTABLE, NULL, NULL);
3031 IC_JTCOND (ic) = cond;
3032 IC_JTLABELS (ic) = labels;
3037 /*-----------------------------------------------------------------*/
3038 /* geniCodeSwitch - changes a switch to a if statement */
3039 /*-----------------------------------------------------------------*/
3041 geniCodeSwitch (ast * tree)
3044 operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
3045 value *caseVals = tree->values.switchVals.swVals;
3046 symbol *trueLabel, *falseLabel;
3048 /* if we can make this a jump table */
3049 if (geniCodeJumpTable (cond, caseVals, tree))
3050 goto jumpTable; /* no need for the comparison */
3052 /* for the cases defined do */
3056 operand *compare = geniCodeLogic (cond,
3057 operandFromValue (caseVals),
3060 sprintf (buffer, "_case_%d_%d",
3061 tree->values.switchVals.swNum,
3062 (int) floatFromVal (caseVals));
3063 trueLabel = newiTempLabel (buffer);
3065 ic = newiCodeCondition (compare, trueLabel, NULL);
3067 caseVals = caseVals->next;
3072 /* if default is present then goto break else break */
3073 if (tree->values.switchVals.swDefault)
3074 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3076 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3078 falseLabel = newiTempLabel (buffer);
3079 geniCodeGoto (falseLabel);
3082 ast2iCode (tree->right);
3085 /*-----------------------------------------------------------------*/
3086 /* geniCodeInline - intermediate code for inline assembler */
3087 /*-----------------------------------------------------------------*/
3089 geniCodeInline (ast * tree)
3093 ic = newiCode (INLINEASM, NULL, NULL);
3094 IC_INLINE (ic) = tree->values.inlineasm;
3098 /*-----------------------------------------------------------------*/
3099 /* ast2iCode - creates an icodeList from an ast */
3100 /*-----------------------------------------------------------------*/
3102 ast2iCode (ast * tree)
3104 operand *left = NULL;
3105 operand *right = NULL;
3110 /* set the global variables for filename & line number */
3112 filename = tree->filename;
3114 lineno = tree->lineno;
3116 block = tree->block;
3118 scopeLevel = tree->level;
3120 if (tree->type == EX_VALUE)
3121 return operandFromValue (tree->opval.val);
3123 if (tree->type == EX_LINK)
3124 return operandFromLink (tree->opval.lnk);
3126 /* if we find a nullop */
3127 if (tree->type == EX_OP &&
3128 (tree->opval.op == NULLOP ||
3129 tree->opval.op == BLOCK))
3131 ast2iCode (tree->left);
3132 ast2iCode (tree->right);
3136 /* special cases for not evaluating */
3137 if (tree->opval.op != ':' &&
3138 tree->opval.op != '?' &&
3139 tree->opval.op != CALL &&
3140 tree->opval.op != IFX &&
3141 tree->opval.op != LABEL &&
3142 tree->opval.op != GOTO &&
3143 tree->opval.op != SWITCH &&
3144 tree->opval.op != FUNCTION &&
3145 tree->opval.op != INLINEASM)
3148 if (IS_ASSIGN_OP (tree->opval.op) ||
3149 IS_DEREF_OP (tree) ||
3150 (tree->opval.op == '&' && !tree->right) ||
3151 tree->opval.op == PTR_OP)
3154 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3155 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3157 int olvr = lvaluereq;
3159 left = operandFromAst (tree->left);
3160 lvaluereq = olvr - 1;
3164 left = operandFromAst (tree->left);
3167 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3168 left = geniCodeRValue (left, TRUE);
3172 left = operandFromAst (tree->left);
3174 if (tree->opval.op == INC_OP ||
3175 tree->opval.op == DEC_OP)
3178 right = operandFromAst (tree->right);
3183 right = operandFromAst (tree->right);
3187 /* now depending on the type of operand */
3188 /* this will be a biggy */
3189 switch (tree->opval.op)
3192 case '[': /* array operation */
3194 sym_link *ltype = operandType (left);
3195 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3196 right = geniCodeRValue (right, TRUE);
3199 return geniCodeArray (left, right);
3201 case '.': /* structure dereference */
3202 if (IS_PTR (operandType (left)))
3203 left = geniCodeRValue (left, TRUE);
3205 left = geniCodeRValue (left, FALSE);
3207 return geniCodeStruct (left, right, tree->lvalue);
3209 case PTR_OP: /* structure pointer dereference */
3212 pType = operandType (left);
3213 left = geniCodeRValue (left, TRUE);
3215 setOClass (pType, getSpec (operandType (left)));
3218 return geniCodeStruct (left, right, tree->lvalue);
3220 case INC_OP: /* increment operator */
3222 return geniCodePostInc (left);
3224 return geniCodePreInc (right);
3226 case DEC_OP: /* decrement operator */
3228 return geniCodePostDec (left);
3230 return geniCodePreDec (right);
3232 case '&': /* bitwise and or address of operator */
3234 { /* this is a bitwise operator */
3235 left = geniCodeRValue (left, FALSE);
3236 right = geniCodeRValue (right, FALSE);
3237 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3240 return geniCodeAddressOf (left);
3242 case '|': /* bitwise or & xor */
3244 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3245 geniCodeRValue (right, FALSE),
3250 return geniCodeDivision (geniCodeRValue (left, FALSE),
3251 geniCodeRValue (right, FALSE));
3254 return geniCodeModulus (geniCodeRValue (left, FALSE),
3255 geniCodeRValue (right, FALSE));
3258 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3259 geniCodeRValue (right, FALSE), FALSE,IS_INT(tree->ftype));
3261 return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
3265 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3266 geniCodeRValue (right, FALSE));
3268 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3272 return geniCodeAdd (geniCodeRValue (left, FALSE),
3273 geniCodeRValue (right, FALSE));
3275 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3278 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3279 geniCodeRValue (right, FALSE));
3282 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3283 geniCodeRValue (right, FALSE));
3285 return geniCodeCast (operandType (left),
3286 geniCodeRValue (right, FALSE), FALSE);
3292 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3296 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3297 setOperandType (op, UCHARTYPE);
3308 return geniCodeLogic (geniCodeRValue (left, FALSE),
3309 geniCodeRValue (right, FALSE),
3312 return geniCodeConditional (tree);
3315 return operandFromLit (getSize (tree->right->ftype));
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);
3327 geniCodeAssign (left, right, 0);
3332 geniCodeAssign (left,
3333 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3335 geniCodeRValue (right, FALSE), FALSE,FALSE), 0);
3339 geniCodeAssign (left,
3340 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3342 geniCodeRValue (right, FALSE)), 0);
3345 geniCodeAssign (left,
3346 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3348 geniCodeRValue (right, FALSE)), 0);
3351 sym_link *rtype = operandType (right);
3352 sym_link *ltype = operandType (left);
3353 if (IS_PTR (rtype) && IS_ITEMP (right)
3354 && right->isaddr && checkType (rtype->next, ltype) == 1)
3355 right = geniCodeRValue (right, TRUE);
3357 right = geniCodeRValue (right, FALSE);
3360 return geniCodeAssign (left,
3361 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3367 sym_link *rtype = operandType (right);
3368 sym_link *ltype = operandType (left);
3369 if (IS_PTR (rtype) && IS_ITEMP (right)
3370 && right->isaddr && checkType (rtype->next, ltype) == 1)
3372 right = geniCodeRValue (right, TRUE);
3376 right = geniCodeRValue (right, FALSE);
3379 geniCodeAssign (left,
3380 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3386 geniCodeAssign (left,
3387 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3389 geniCodeRValue (right, FALSE)), 0);
3392 geniCodeAssign (left,
3393 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3395 geniCodeRValue (right, FALSE)), 0);
3398 geniCodeAssign (left,
3399 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3401 geniCodeRValue (right, FALSE),
3403 operandType (left)), 0);
3406 geniCodeAssign (left,
3407 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3409 geniCodeRValue (right, FALSE),
3411 operandType (left)), 0);
3414 geniCodeAssign (left,
3415 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3417 geniCodeRValue (right, FALSE),
3419 operandType (left)), 0);
3421 return geniCodeRValue (right, FALSE);
3424 return geniCodeCall (ast2iCode (tree->left),
3427 geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
3428 return ast2iCode (tree->right);
3431 geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
3432 return ast2iCode (tree->right);
3435 geniCodeFunctionBody (tree);
3439 geniCodeReturn (right);
3447 geniCodeSwitch (tree);
3451 geniCodeInline (tree);
3458 /*-----------------------------------------------------------------*/
3459 /* reverseICChain - gets from the list and creates a linkedlist */
3460 /*-----------------------------------------------------------------*/
3467 while ((loop = getSet (&iCodeChain)))
3479 /*-----------------------------------------------------------------*/
3480 /* iCodeFromAst - given an ast will convert it to iCode */
3481 /*-----------------------------------------------------------------*/
3483 iCodeFromAst (ast * tree)
3485 returnLabel = newiTempLabel ("_return");
3486 entryLabel = newiTempLabel ("_entry");
3488 return reverseiCChain ();