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);
1679 /* if the right is a literal & power of 2 */
1680 /* then make it a left shift */
1681 /*If we are computing ptr size then normal multiplication */
1682 /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
1683 /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
1684 if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
1685 !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
1686 (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
1688 if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)))
1690 /* LEFT_OP need same size for left and result, */
1691 left = geniCodeCast (resType, left, TRUE);
1692 ltype = operandType (left);
1694 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1698 ic = newiCode ('*', left, right); /* normal multiplication */
1699 /* if the size left or right > 1 then support routine */
1700 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1704 IC_RESULT (ic) = newiTempOperand (resType, 1);
1707 return IC_RESULT (ic);
1710 /*-----------------------------------------------------------------*/
1711 /* geniCodeDivision - gen intermediate code for division */
1712 /*-----------------------------------------------------------------*/
1714 geniCodeDivision (operand * left, operand * right)
1719 sym_link *rtype = operandType (right);
1720 sym_link *retype = getSpec (rtype);
1721 sym_link *ltype = operandType (left);
1722 sym_link *letype = getSpec (ltype);
1724 resType = usualBinaryConversions (&left, &right);
1726 /* if the right is a literal & power of 2 */
1727 /* then make it a right shift */
1728 if (IS_LITERAL (retype) &&
1729 !IS_FLOAT (letype) &&
1730 (p2 = powof2 ((unsigned long)
1731 floatFromVal (right->operand.valOperand))))
1732 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1735 ic = newiCode ('/', left, right); /* normal division */
1736 /* if the size left or right > 1 then support routine */
1737 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1740 IC_RESULT (ic) = newiTempOperand (resType, 0);
1743 return IC_RESULT (ic);
1745 /*-----------------------------------------------------------------*/
1746 /* geniCodeModulus - gen intermediate code for modulus */
1747 /*-----------------------------------------------------------------*/
1749 geniCodeModulus (operand * left, operand * right)
1755 /* if they are both literal then we know the result */
1756 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1757 return operandFromValue (valMod (left->operand.valOperand,
1758 right->operand.valOperand));
1760 resType = usualBinaryConversions (&left, &right);
1762 /* now they are the same size */
1763 ic = newiCode ('%', left, right);
1765 /* if the size left or right > 1 then support routine */
1766 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1768 IC_RESULT (ic) = newiTempOperand (resType, 0);
1771 return IC_RESULT (ic);
1774 /*-----------------------------------------------------------------*/
1775 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1776 /*-----------------------------------------------------------------*/
1778 geniCodePtrPtrSubtract (operand * left, operand * right)
1784 /* if they are both literals then */
1785 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1787 result = operandFromValue (valMinus (left->operand.valOperand,
1788 right->operand.valOperand));
1792 ic = newiCode ('-', left, right);
1794 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1798 return geniCodeDivision (result,
1799 operandFromLit (getSize (ltype->next)));
1802 /*-----------------------------------------------------------------*/
1803 /* geniCodeSubtract - generates code for subtraction */
1804 /*-----------------------------------------------------------------*/
1806 geniCodeSubtract (operand * left, operand * right)
1813 /* if they both pointers then */
1814 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1815 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1816 return geniCodePtrPtrSubtract (left, right);
1818 /* if they are both literal then we know the result */
1819 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1820 && left->isLiteral && right->isLiteral)
1821 return operandFromValue (valMinus (left->operand.valOperand,
1822 right->operand.valOperand));
1824 /* if left is an array or pointer */
1825 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1827 isarray = left->isaddr;
1828 right = geniCodeMultiply (right,
1829 operandFromLit (getSize (ltype->next)), TRUE);
1830 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1833 { /* make them the same size */
1834 resType = usualBinaryConversions (&left, &right);
1837 ic = newiCode ('-', left, right);
1839 IC_RESULT (ic) = newiTempOperand (resType, 1);
1840 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1842 /* if left or right is a float */
1843 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1847 return IC_RESULT (ic);
1850 /*-----------------------------------------------------------------*/
1851 /* geniCodeAdd - generates iCode for addition */
1852 /*-----------------------------------------------------------------*/
1854 geniCodeAdd (operand * left, operand * right)
1862 /* if left is an array then array access */
1863 if (IS_ARRAY (ltype))
1864 return geniCodeArray (left, right);
1866 /* if the right side is LITERAL zero */
1867 /* return the left side */
1868 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1871 /* if left is literal zero return right */
1872 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1875 /* if left is an array or pointer then size */
1879 isarray = left->isaddr;
1881 operandFromLit (getSize (ltype->next));
1883 right = geniCodeMultiply (right, size, (getSize (ltype) != 1));
1885 resType = copyLinkChain (ltype);
1888 { /* make them the same size */
1889 resType = usualBinaryConversions (&left, &right);
1892 /* if they are both literals then we know */
1893 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1894 && left->isLiteral && right->isLiteral)
1895 return operandFromValue (valPlus (valFromType (letype),
1896 valFromType (retype)));
1898 ic = newiCode ('+', left, right);
1900 IC_RESULT (ic) = newiTempOperand (resType, 1);
1901 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1903 /* if left or right is a float then support
1905 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1910 return IC_RESULT (ic);
1914 /*-----------------------------------------------------------------*/
1915 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1916 /*-----------------------------------------------------------------*/
1918 aggrToPtr (sym_link * type, bool force)
1924 if (IS_PTR (type) && !force)
1927 etype = getSpec (type);
1931 /* if the output class is generic */
1932 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1933 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1935 /* if the variable was declared a constant */
1936 /* then the pointer points to a constant */
1937 if (IS_CONSTANT (etype))
1938 DCL_PTR_CONST (ptype) = 1;
1940 /* the variable was volatile then pointer to volatile */
1941 if (IS_VOLATILE (etype))
1942 DCL_PTR_VOLATILE (ptype) = 1;
1946 /*-----------------------------------------------------------------*/
1947 /* geniCodeArray2Ptr - array to pointer */
1948 /*-----------------------------------------------------------------*/
1950 geniCodeArray2Ptr (operand * op)
1952 sym_link *optype = operandType (op);
1953 sym_link *opetype = getSpec (optype);
1955 /* set the pointer depending on the storage class */
1956 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1957 DCL_PTR_CONST (optype) = port->mem.code_ro;
1960 /* if the variable was declared a constant */
1961 /* then the pointer points to a constant */
1962 if (IS_CONSTANT (opetype))
1963 DCL_PTR_CONST (optype) = 1;
1965 /* the variable was volatile then pointer to volatile */
1966 if (IS_VOLATILE (opetype))
1967 DCL_PTR_VOLATILE (optype) = 1;
1973 /*-----------------------------------------------------------------*/
1974 /* geniCodeArray - array access */
1975 /*-----------------------------------------------------------------*/
1977 geniCodeArray (operand * left, operand * right)
1980 sym_link *ltype = operandType (left);
1984 if (IS_PTR (ltype->next) && left->isaddr)
1986 left = geniCodeRValue (left, FALSE);
1988 return geniCodeDerefPtr (geniCodeAdd (left, right));
1992 right = geniCodeMultiply (right,
1993 operandFromLit (getSize (ltype->next)), TRUE);
1995 /* we can check for limits here */
1996 if (isOperandLiteral (right) &&
1999 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2001 werror (E_ARRAY_BOUND);
2002 right = operandFromLit (0);
2005 ic = newiCode ('+', left, right);
2007 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2008 !IS_AGGREGATE (ltype->next) &&
2009 !IS_PTR (ltype->next))
2010 ? ltype : ltype->next), 0);
2012 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2014 return IC_RESULT (ic);
2017 /*-----------------------------------------------------------------*/
2018 /* geniCodeStruct - generates intermediate code for structres */
2019 /*-----------------------------------------------------------------*/
2021 geniCodeStruct (operand * left, operand * right, bool islval)
2024 sym_link *type = operandType (left);
2025 sym_link *etype = getSpec (type);
2027 symbol *element = getStructElement (SPEC_STRUCT (etype),
2028 right->operand.symOperand);
2030 /* add the offset */
2031 ic = newiCode ('+', left, operandFromLit (element->offset));
2033 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2035 /* preserve the storage & output class of the struct */
2036 /* as well as the volatile attribute */
2037 retype = getSpec (operandType (IC_RESULT (ic)));
2038 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2039 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2040 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2042 if (IS_PTR (element->type))
2043 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2045 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2049 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2052 /*-----------------------------------------------------------------*/
2053 /* geniCodePostInc - generate int code for Post increment */
2054 /*-----------------------------------------------------------------*/
2056 geniCodePostInc (operand * op)
2060 sym_link *optype = operandType (op);
2062 operand *rv = (IS_ITEMP (op) ?
2063 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2065 sym_link *rvtype = operandType (rv);
2068 /* if this is not an address we have trouble */
2071 werror (E_LVALUE_REQUIRED, "++");
2075 rOp = newiTempOperand (rvtype, 0);
2081 geniCodeAssign (rOp, rv, 0);
2083 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2084 if (IS_FLOAT (rvtype))
2085 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2087 ic = newiCode ('+', rv, operandFromLit (size));
2089 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2092 geniCodeAssign (op, result, 0);
2098 /*-----------------------------------------------------------------*/
2099 /* geniCodePreInc - generate code for preIncrement */
2100 /*-----------------------------------------------------------------*/
2102 geniCodePreInc (operand * op)
2105 sym_link *optype = operandType (op);
2106 operand *rop = (IS_ITEMP (op) ?
2107 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2109 sym_link *roptype = operandType (rop);
2115 werror (E_LVALUE_REQUIRED, "++");
2120 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2121 if (IS_FLOAT (roptype))
2122 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2124 ic = newiCode ('+', rop, operandFromLit (size));
2125 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2129 return geniCodeAssign (op, result, 0);
2132 /*-----------------------------------------------------------------*/
2133 /* geniCodePostDec - generates code for Post decrement */
2134 /*-----------------------------------------------------------------*/
2136 geniCodePostDec (operand * op)
2140 sym_link *optype = operandType (op);
2142 operand *rv = (IS_ITEMP (op) ?
2143 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2145 sym_link *rvtype = operandType (rv);
2148 /* if this is not an address we have trouble */
2151 werror (E_LVALUE_REQUIRED, "++");
2155 rOp = newiTempOperand (rvtype, 0);
2161 geniCodeAssign (rOp, rv, 0);
2163 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2164 if (IS_FLOAT (rvtype))
2165 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2167 ic = newiCode ('-', rv, operandFromLit (size));
2169 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2172 geniCodeAssign (op, result, 0);
2178 /*-----------------------------------------------------------------*/
2179 /* geniCodePreDec - generate code for pre decrement */
2180 /*-----------------------------------------------------------------*/
2182 geniCodePreDec (operand * op)
2185 sym_link *optype = operandType (op);
2186 operand *rop = (IS_ITEMP (op) ?
2187 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2189 sym_link *roptype = operandType (rop);
2195 werror (E_LVALUE_REQUIRED, "++");
2200 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2201 if (IS_FLOAT (roptype))
2202 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2204 ic = newiCode ('-', rop, operandFromLit (size));
2205 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2209 return geniCodeAssign (op, result, 0);
2213 /*-----------------------------------------------------------------*/
2214 /* geniCodeBitwise - gen int code for bitWise operators */
2215 /*-----------------------------------------------------------------*/
2217 geniCodeBitwise (operand * left, operand * right,
2218 int oper, sym_link * resType)
2222 left = geniCodeCast (resType, left, TRUE);
2223 right = geniCodeCast (resType, right, TRUE);
2225 ic = newiCode (oper, left, right);
2226 IC_RESULT (ic) = newiTempOperand (resType, 0);
2229 return IC_RESULT (ic);
2232 /*-----------------------------------------------------------------*/
2233 /* geniCodeAddressOf - gens icode for '&' address of operator */
2234 /*-----------------------------------------------------------------*/
2236 geniCodeAddressOf (operand * op)
2240 sym_link *optype = operandType (op);
2241 sym_link *opetype = getSpec (optype);
2243 /* lvalue check already done in decorateType */
2244 /* this must be a lvalue */
2245 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2246 /* werror (E_LVALUE_REQUIRED,"&"); */
2251 p->class = DECLARATOR;
2253 /* set the pointer depending on the storage class */
2254 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2255 DCL_PTR_CONST (p) = port->mem.code_ro;
2257 /* make sure we preserve the const & volatile */
2258 if (IS_CONSTANT (opetype))
2259 DCL_PTR_CONST (p) = 1;
2261 if (IS_VOLATILE (opetype))
2262 DCL_PTR_VOLATILE (p) = 1;
2264 p->next = copyLinkChain (optype);
2266 /* if already a temp */
2269 setOperandType (op, p);
2274 /* other wise make this of the type coming in */
2275 ic = newiCode (ADDRESS_OF, op, NULL);
2276 IC_RESULT (ic) = newiTempOperand (p, 1);
2277 IC_RESULT (ic)->isaddr = 0;
2279 return IC_RESULT (ic);
2281 /*-----------------------------------------------------------------*/
2282 /* setOClass - sets the output class depending on the pointer type */
2283 /*-----------------------------------------------------------------*/
2285 setOClass (sym_link * ptr, sym_link * spec)
2287 switch (DCL_TYPE (ptr))
2290 SPEC_OCLS (spec) = data;
2294 SPEC_OCLS (spec) = generic;
2298 SPEC_OCLS (spec) = xdata;
2302 SPEC_OCLS (spec) = code;
2306 SPEC_OCLS (spec) = idata;
2310 SPEC_OCLS (spec) = xstack;
2314 SPEC_OCLS (spec) = eeprom;
2323 /*-----------------------------------------------------------------*/
2324 /* geniCodeDerefPtr - dereference pointer with '*' */
2325 /*-----------------------------------------------------------------*/
2327 geniCodeDerefPtr (operand * op)
2329 sym_link *rtype, *retype;
2330 sym_link *optype = operandType (op);
2332 /* if this is a pointer then generate the rvalue */
2333 if (IS_PTR (optype))
2335 if (IS_TRUE_SYMOP (op))
2338 op = geniCodeRValue (op, TRUE);
2341 op = geniCodeRValue (op, TRUE);
2344 /* now get rid of the pointer part */
2345 if (lvaluereq && IS_ITEMP (op))
2347 retype = getSpec (rtype = copyLinkChain (optype));
2351 retype = getSpec (rtype = copyLinkChain (optype->next));
2354 /* if this is a pointer then outputclass needs 2b updated */
2355 if (IS_PTR (optype))
2356 setOClass (optype, retype);
2358 op->isGptr = IS_GENPTR (optype);
2360 /* if the pointer was declared as a constant */
2361 /* then we cannot allow assignment to the derefed */
2362 if (IS_PTR_CONST (optype))
2363 SPEC_CONST (retype) = 1;
2365 op->isaddr = (IS_PTR (rtype) ||
2366 IS_STRUCT (rtype) ||
2372 op = geniCodeRValue (op, TRUE);
2374 setOperandType (op, rtype);
2379 /*-----------------------------------------------------------------*/
2380 /* geniCodeUnaryMinus - does a unary minus of the operand */
2381 /*-----------------------------------------------------------------*/
2383 geniCodeUnaryMinus (operand * op)
2386 sym_link *optype = operandType (op);
2388 if (IS_LITERAL (optype))
2389 return operandFromLit (-floatFromVal (op->operand.valOperand));
2391 ic = newiCode (UNARYMINUS, op, NULL);
2392 IC_RESULT (ic) = newiTempOperand (optype, 0);
2394 return IC_RESULT (ic);
2397 /*-----------------------------------------------------------------*/
2398 /* geniCodeLeftShift - gen i code for left shift */
2399 /*-----------------------------------------------------------------*/
2401 geniCodeLeftShift (operand * left, operand * right)
2406 /* Note that we don't use the usual binary conversions for the
2407 * shift operations, in accordance with our ANSI friends.
2409 if (options.ANSIint)
2411 right = usualUnaryConversions (right);
2412 left = usualUnaryConversions (left);
2415 ic = newiCode (LEFT_OP, left, right);
2416 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2418 return IC_RESULT (ic);
2421 /*-----------------------------------------------------------------*/
2422 /* geniCodeRightShift - gen i code for right shift */
2423 /*-----------------------------------------------------------------*/
2425 geniCodeRightShift (operand * left, operand * right)
2430 /* Note that we don't use the usual binary conversions for the
2431 * shift operations, in accordance with our ANSI friends.
2433 if (options.ANSIint)
2435 right = usualUnaryConversions (right);
2436 left = usualUnaryConversions (left);
2439 ic = newiCode (RIGHT_OP, left, right);
2440 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2442 return IC_RESULT (ic);
2445 #if defined(__BORLANDC__) || defined(_MSC_VER)
2446 #define LONG_LONG __int64
2448 #define LONG_LONG long long
2451 /*-----------------------------------------------------------------*/
2452 /* geniCodeLogic- logic code */
2453 /*-----------------------------------------------------------------*/
2455 geniCodeLogic (operand * left, operand * right, int op)
2459 sym_link *rtype = operandType (right);
2460 sym_link *ltype = operandType (left);
2462 /* left is integral type and right is literal then
2463 check if the literal value is within bounds */
2464 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2466 int nbits = bitsForType (ltype);
2467 long v = operandLitValue (right);
2469 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2470 werror (W_CONST_RANGE, " compare operation ");
2473 ctype = usualBinaryConversions (&left, &right);
2475 ic = newiCode (op, left, right);
2476 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2478 /* if comparing anything greater than one byte
2479 and not a '==' || '!=' || '&&' || '||' (these
2481 if (getSize (ctype) > 1 &&
2489 return IC_RESULT (ic);
2492 /*-----------------------------------------------------------------*/
2493 /* geniCodeUnary - for a a generic unary operation */
2494 /*-----------------------------------------------------------------*/
2496 geniCodeUnary (operand * op, int oper)
2498 iCode *ic = newiCode (oper, op, NULL);
2500 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2502 return IC_RESULT (ic);
2505 /*-----------------------------------------------------------------*/
2506 /* geniCodeConditional - geniCode for '?' ':' operation */
2507 /*-----------------------------------------------------------------*/
2509 geniCodeConditional (ast * tree)
2512 symbol *falseLabel = newiTempLabel (NULL);
2513 symbol *exitLabel = newiTempLabel (NULL);
2514 operand *cond = ast2iCode (tree->left);
2515 operand *true, *false, *result;
2517 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2521 true = ast2iCode (tree->right->left);
2523 /* move the value to a new Operand */
2524 result = newiTempOperand (operandType (true), 0);
2525 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2527 /* generate an unconditional goto */
2528 geniCodeGoto (exitLabel);
2530 /* now for the right side */
2531 geniCodeLabel (falseLabel);
2533 false = ast2iCode (tree->right->right);
2534 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2536 /* create the exit label */
2537 geniCodeLabel (exitLabel);
2542 /*-----------------------------------------------------------------*/
2543 /* geniCodeAssign - generate code for assignment */
2544 /*-----------------------------------------------------------------*/
2546 geniCodeAssign (operand * left, operand * right, int nosupdate)
2549 sym_link *ltype = operandType (left);
2550 sym_link *rtype = operandType (right);
2552 if (!left->isaddr && !IS_ITEMP (left))
2554 werror (E_LVALUE_REQUIRED, "assignment");
2558 /* left is integral type and right is literal then
2559 check if the literal value is within bounds */
2560 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2562 int nbits = bitsForType (ltype);
2563 long v = operandLitValue (right);
2565 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2566 werror (W_CONST_RANGE, " = operation");
2569 /* if the left & right type don't exactly match */
2570 /* if pointer set then make sure the check is
2571 done with the type & not the pointer */
2572 /* then cast rights type to left */
2574 /* first check the type for pointer assignement */
2575 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2576 checkType (ltype, rtype) < 0)
2578 if (checkType (ltype->next, rtype) < 0)
2579 right = geniCodeCast (ltype->next, right, TRUE);
2581 else if (checkType (ltype, rtype) < 0)
2582 right = geniCodeCast (ltype, right, TRUE);
2584 /* if left is a true symbol & ! volatile
2585 create an assignment to temporary for
2586 the right & then assign this temporary
2587 to the symbol this is SSA . isn't it simple
2588 and folks have published mountains of paper on it */
2589 if (IS_TRUE_SYMOP (left) &&
2590 !isOperandVolatile (left, FALSE) &&
2591 isOperandGlobal (left))
2595 if (IS_TRUE_SYMOP (right))
2596 sym = OP_SYMBOL (right);
2597 ic = newiCode ('=', NULL, right);
2598 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2599 SPIL_LOC (right) = sym;
2603 ic = newiCode ('=', NULL, right);
2604 IC_RESULT (ic) = left;
2607 /* if left isgptr flag is set then support
2608 routine will be required */
2612 ic->nosupdate = nosupdate;
2616 /*-----------------------------------------------------------------*/
2617 /* geniCodeSEParms - generate code for side effecting fcalls */
2618 /*-----------------------------------------------------------------*/
2620 geniCodeSEParms (ast * parms)
2625 if (parms->type == EX_OP && parms->opval.op == PARAM)
2627 geniCodeSEParms (parms->left);
2628 geniCodeSEParms (parms->right);
2632 /* hack don't like this but too lazy to think of
2634 if (IS_ADDRESS_OF_OP (parms))
2635 parms->left->lvalue = 1;
2637 if (IS_CAST_OP (parms) &&
2638 IS_PTR (parms->ftype) &&
2639 IS_ADDRESS_OF_OP (parms->right))
2640 parms->right->left->lvalue = 1;
2642 parms->opval.oprnd =
2643 geniCodeRValue (ast2iCode (parms), FALSE);
2645 parms->type = EX_OPERAND;
2648 /*-----------------------------------------------------------------*/
2649 /* geniCodeParms - generates parameters */
2650 /*-----------------------------------------------------------------*/
2652 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
2660 /* if this is a param node then do the left & right */
2661 if (parms->type == EX_OP && parms->opval.op == PARAM)
2663 geniCodeParms (parms->left, stack, fetype, func);
2664 geniCodeParms (parms->right, stack, fetype, func);
2668 /* get the parameter value */
2669 if (parms->type == EX_OPERAND)
2670 pval = parms->opval.oprnd;
2673 /* maybe this else should go away ?? */
2674 /* hack don't like this but too lazy to think of
2676 if (IS_ADDRESS_OF_OP (parms))
2677 parms->left->lvalue = 1;
2679 if (IS_CAST_OP (parms) &&
2680 IS_PTR (parms->ftype) &&
2681 IS_ADDRESS_OF_OP (parms->right))
2682 parms->right->left->lvalue = 1;
2684 pval = geniCodeRValue (ast2iCode (parms), FALSE);
2687 /* if register parm then make it a send */
2688 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2689 IS_REGPARM (parms->etype)) && !func->hasVargs)
2691 ic = newiCode (SEND, pval, NULL);
2696 /* now decide whether to push or assign */
2697 if (!(options.stackAuto || IS_RENT (fetype)))
2701 operand *top = operandFromSymbol (parms->argSym);
2702 geniCodeAssign (top, pval, 1);
2706 sym_link *p = operandType (pval);
2708 ic = newiCode (IPUSH, pval, NULL);
2710 /* update the stack adjustment */
2711 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2718 /*-----------------------------------------------------------------*/
2719 /* geniCodeCall - generates temp code for calling */
2720 /*-----------------------------------------------------------------*/
2722 geniCodeCall (operand * left, ast * parms)
2726 sym_link *type, *etype;
2729 /* take care of parameters with side-effecting
2730 function calls in them, this is required to take care
2731 of overlaying function parameters */
2732 geniCodeSEParms (parms);
2734 /* first the parameters */
2735 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
2737 /* now call : if symbol then pcall */
2738 if (IS_ITEMP (left))
2739 ic = newiCode (PCALL, left, NULL);
2741 ic = newiCode (CALL, left, NULL);
2743 IC_ARGS (ic) = left->operand.symOperand->args;
2744 type = copyLinkChain (operandType (left)->next);
2745 etype = getSpec (type);
2746 SPEC_EXTR (etype) = 0;
2747 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2751 /* stack adjustment after call */
2752 left->parmBytes = stack;
2757 /*-----------------------------------------------------------------*/
2758 /* geniCodeReceive - generate intermediate code for "receive" */
2759 /*-----------------------------------------------------------------*/
2761 geniCodeReceive (value * args)
2763 /* for all arguments that are passed in registers */
2767 if (IS_REGPARM (args->etype))
2769 operand *opr = operandFromValue (args);
2771 symbol *sym = OP_SYMBOL (opr);
2774 /* we will use it after all optimizations
2775 and before liveRange calculation */
2776 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2779 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2780 options.stackAuto == 0 &&
2786 opl = newiTempOperand (args->type, 0);
2788 sym->reqv->key = sym->key;
2789 OP_SYMBOL (sym->reqv)->key = sym->key;
2790 OP_SYMBOL (sym->reqv)->isreqv = 1;
2791 OP_SYMBOL (sym->reqv)->islocal = 0;
2792 SPIL_LOC (sym->reqv) = sym;
2796 ic = newiCode (RECEIVE, NULL, NULL);
2797 currFunc->recvSize = getSize (sym->etype);
2798 IC_RESULT (ic) = opr;
2806 /*-----------------------------------------------------------------*/
2807 /* geniCodeFunctionBody - create the function body */
2808 /*-----------------------------------------------------------------*/
2810 geniCodeFunctionBody (ast * tree)
2817 /* reset the auto generation */
2823 func = ast2iCode (tree->left);
2824 fetype = getSpec (operandType (func));
2826 savelineno = lineno;
2827 lineno = OP_SYMBOL (func)->lineDef;
2828 /* create an entry label */
2829 geniCodeLabel (entryLabel);
2830 lineno = savelineno;
2832 /* create a proc icode */
2833 ic = newiCode (FUNCTION, func, NULL);
2834 /* if the function has parmas then */
2835 /* save the parameters information */
2836 ic->argLabel.args = tree->values.args;
2837 ic->lineno = OP_SYMBOL (func)->lineDef;
2841 /* for all parameters that are passed
2842 on registers add a "receive" */
2843 geniCodeReceive (tree->values.args);
2845 /* generate code for the body */
2846 ast2iCode (tree->right);
2848 /* create a label for return */
2849 geniCodeLabel (returnLabel);
2851 /* now generate the end proc */
2852 ic = newiCode (ENDFUNCTION, func, NULL);
2857 /*-----------------------------------------------------------------*/
2858 /* geniCodeReturn - gen icode for 'return' statement */
2859 /*-----------------------------------------------------------------*/
2861 geniCodeReturn (operand * op)
2865 /* if the operand is present force an rvalue */
2867 op = geniCodeRValue (op, FALSE);
2869 ic = newiCode (RETURN, op, NULL);
2873 /*-----------------------------------------------------------------*/
2874 /* geniCodeIfx - generates code for extended if statement */
2875 /*-----------------------------------------------------------------*/
2877 geniCodeIfx (ast * tree)
2880 operand *condition = ast2iCode (tree->left);
2883 /* if condition is null then exit */
2887 condition = geniCodeRValue (condition, FALSE);
2889 cetype = getSpec (operandType (condition));
2890 /* if the condition is a literal */
2891 if (IS_LITERAL (cetype))
2893 if (floatFromVal (condition->operand.valOperand))
2895 if (tree->trueLabel)
2896 geniCodeGoto (tree->trueLabel);
2902 if (tree->falseLabel)
2903 geniCodeGoto (tree->falseLabel);
2910 if (tree->trueLabel)
2912 ic = newiCodeCondition (condition,
2917 if (tree->falseLabel)
2918 geniCodeGoto (tree->falseLabel);
2922 ic = newiCodeCondition (condition,
2929 ast2iCode (tree->right);
2932 /*-----------------------------------------------------------------*/
2933 /* geniCodeJumpTable - tries to create a jump table for switch */
2934 /*-----------------------------------------------------------------*/
2936 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2938 int min = 0, max = 0, t, cnt = 0;
2945 if (!tree || !caseVals)
2948 /* the criteria for creating a jump table is */
2949 /* all integer numbers between the maximum & minimum must */
2950 /* be present , the maximum value should not exceed 255 */
2951 min = max = (int) floatFromVal (vch = caseVals);
2952 sprintf (buffer, "_case_%d_%d",
2953 tree->values.switchVals.swNum,
2955 addSet (&labels, newiTempLabel (buffer));
2957 /* if there is only one case value then no need */
2958 if (!(vch = vch->next))
2963 if (((t = (int) floatFromVal (vch)) - max) != 1)
2965 sprintf (buffer, "_case_%d_%d",
2966 tree->values.switchVals.swNum,
2968 addSet (&labels, newiTempLabel (buffer));
2974 /* if the number of case statements <= 2 then */
2975 /* it is not economical to create the jump table */
2976 /* since two compares are needed for boundary conditions */
2977 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2980 if (tree->values.switchVals.swDefault)
2981 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2983 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2985 falseLabel = newiTempLabel (buffer);
2987 /* so we can create a jumptable */
2988 /* first we rule out the boundary conditions */
2989 /* if only optimization says so */
2990 if (!optimize.noJTabBoundary)
2992 sym_link *cetype = getSpec (operandType (cond));
2993 /* no need to check the lower bound if
2994 the condition is unsigned & minimum value is zero */
2995 if (!(min == 0 && SPEC_USIGN (cetype)))
2997 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2998 ic = newiCodeCondition (boundary, falseLabel, NULL);
3002 /* now for upper bounds */
3003 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3004 ic = newiCodeCondition (boundary, falseLabel, NULL);
3008 /* if the min is not zero then we no make it zero */
3011 cond = geniCodeSubtract (cond, operandFromLit (min));
3012 setOperandType (cond, UCHARTYPE);
3015 /* now create the jumptable */
3016 ic = newiCode (JUMPTABLE, NULL, NULL);
3017 IC_JTCOND (ic) = cond;
3018 IC_JTLABELS (ic) = labels;
3023 /*-----------------------------------------------------------------*/
3024 /* geniCodeSwitch - changes a switch to a if statement */
3025 /*-----------------------------------------------------------------*/
3027 geniCodeSwitch (ast * tree)
3030 operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
3031 value *caseVals = tree->values.switchVals.swVals;
3032 symbol *trueLabel, *falseLabel;
3034 /* if we can make this a jump table */
3035 if (geniCodeJumpTable (cond, caseVals, tree))
3036 goto jumpTable; /* no need for the comparison */
3038 /* for the cases defined do */
3042 operand *compare = geniCodeLogic (cond,
3043 operandFromValue (caseVals),
3046 sprintf (buffer, "_case_%d_%d",
3047 tree->values.switchVals.swNum,
3048 (int) floatFromVal (caseVals));
3049 trueLabel = newiTempLabel (buffer);
3051 ic = newiCodeCondition (compare, trueLabel, NULL);
3053 caseVals = caseVals->next;
3058 /* if default is present then goto break else break */
3059 if (tree->values.switchVals.swDefault)
3060 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3062 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3064 falseLabel = newiTempLabel (buffer);
3065 geniCodeGoto (falseLabel);
3068 ast2iCode (tree->right);
3071 /*-----------------------------------------------------------------*/
3072 /* geniCodeInline - intermediate code for inline assembler */
3073 /*-----------------------------------------------------------------*/
3075 geniCodeInline (ast * tree)
3079 ic = newiCode (INLINEASM, NULL, NULL);
3080 IC_INLINE (ic) = tree->values.inlineasm;
3084 /*-----------------------------------------------------------------*/
3085 /* ast2iCode - creates an icodeList from an ast */
3086 /*-----------------------------------------------------------------*/
3088 ast2iCode (ast * tree)
3090 operand *left = NULL;
3091 operand *right = NULL;
3096 /* set the global variables for filename & line number */
3098 filename = tree->filename;
3100 lineno = tree->lineno;
3102 block = tree->block;
3104 scopeLevel = tree->level;
3106 if (tree->type == EX_VALUE)
3107 return operandFromValue (tree->opval.val);
3109 if (tree->type == EX_LINK)
3110 return operandFromLink (tree->opval.lnk);
3112 /* if we find a nullop */
3113 if (tree->type == EX_OP &&
3114 (tree->opval.op == NULLOP ||
3115 tree->opval.op == BLOCK))
3117 ast2iCode (tree->left);
3118 ast2iCode (tree->right);
3122 /* special cases for not evaluating */
3123 if (tree->opval.op != ':' &&
3124 tree->opval.op != '?' &&
3125 tree->opval.op != CALL &&
3126 tree->opval.op != IFX &&
3127 tree->opval.op != LABEL &&
3128 tree->opval.op != GOTO &&
3129 tree->opval.op != SWITCH &&
3130 tree->opval.op != FUNCTION &&
3131 tree->opval.op != INLINEASM)
3134 if (IS_ASSIGN_OP (tree->opval.op) ||
3135 IS_DEREF_OP (tree) ||
3136 (tree->opval.op == '&' && !tree->right) ||
3137 tree->opval.op == PTR_OP)
3140 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3141 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3143 int olvr = lvaluereq;
3145 left = operandFromAst (tree->left);
3146 lvaluereq = olvr - 1;
3150 left = operandFromAst (tree->left);
3153 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3154 left = geniCodeRValue (left, TRUE);
3158 left = operandFromAst (tree->left);
3160 if (tree->opval.op == INC_OP ||
3161 tree->opval.op == DEC_OP)
3164 right = operandFromAst (tree->right);
3169 right = operandFromAst (tree->right);
3173 /* now depending on the type of operand */
3174 /* this will be a biggy */
3175 switch (tree->opval.op)
3178 case '[': /* array operation */
3180 sym_link *ltype = operandType (left);
3181 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3182 right = geniCodeRValue (right, TRUE);
3185 return geniCodeArray (left, right);
3187 case '.': /* structure dereference */
3188 if (IS_PTR (operandType (left)))
3189 left = geniCodeRValue (left, TRUE);
3191 left = geniCodeRValue (left, FALSE);
3193 return geniCodeStruct (left, right, tree->lvalue);
3195 case PTR_OP: /* structure pointer dereference */
3198 pType = operandType (left);
3199 left = geniCodeRValue (left, TRUE);
3201 setOClass (pType, getSpec (operandType (left)));
3204 return geniCodeStruct (left, right, tree->lvalue);
3206 case INC_OP: /* increment operator */
3208 return geniCodePostInc (left);
3210 return geniCodePreInc (right);
3212 case DEC_OP: /* decrement operator */
3214 return geniCodePostDec (left);
3216 return geniCodePreDec (right);
3218 case '&': /* bitwise and or address of operator */
3220 { /* this is a bitwise operator */
3221 left = geniCodeRValue (left, FALSE);
3222 right = geniCodeRValue (right, FALSE);
3223 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3226 return geniCodeAddressOf (left);
3228 case '|': /* bitwise or & xor */
3230 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3231 geniCodeRValue (right, FALSE),
3236 return geniCodeDivision (geniCodeRValue (left, FALSE),
3237 geniCodeRValue (right, FALSE));
3240 return geniCodeModulus (geniCodeRValue (left, FALSE),
3241 geniCodeRValue (right, FALSE));
3244 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3245 geniCodeRValue (right, FALSE), FALSE);
3247 return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
3251 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3252 geniCodeRValue (right, FALSE));
3254 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3258 return geniCodeAdd (geniCodeRValue (left, FALSE),
3259 geniCodeRValue (right, FALSE));
3261 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3264 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3265 geniCodeRValue (right, FALSE));
3268 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3269 geniCodeRValue (right, FALSE));
3271 return geniCodeCast (operandType (left),
3272 geniCodeRValue (right, FALSE), FALSE);
3278 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3282 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3283 setOperandType (op, UCHARTYPE);
3294 return geniCodeLogic (geniCodeRValue (left, FALSE),
3295 geniCodeRValue (right, FALSE),
3298 return geniCodeConditional (tree);
3301 return operandFromLit (getSize (tree->right->ftype));
3305 sym_link *rtype = operandType (right);
3306 sym_link *ltype = operandType (left);
3307 if (IS_PTR (rtype) && IS_ITEMP (right)
3308 && right->isaddr && checkType (rtype->next, ltype) == 1)
3309 right = geniCodeRValue (right, TRUE);
3311 right = geniCodeRValue (right, FALSE);
3313 geniCodeAssign (left, right, 0);
3318 geniCodeAssign (left,
3319 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3321 geniCodeRValue (right, FALSE), FALSE), 0);
3325 geniCodeAssign (left,
3326 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3328 geniCodeRValue (right, FALSE)), 0);
3331 geniCodeAssign (left,
3332 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3334 geniCodeRValue (right, FALSE)), 0);
3337 sym_link *rtype = operandType (right);
3338 sym_link *ltype = operandType (left);
3339 if (IS_PTR (rtype) && IS_ITEMP (right)
3340 && right->isaddr && checkType (rtype->next, ltype) == 1)
3341 right = geniCodeRValue (right, TRUE);
3343 right = geniCodeRValue (right, FALSE);
3346 return geniCodeAssign (left,
3347 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3353 sym_link *rtype = operandType (right);
3354 sym_link *ltype = operandType (left);
3355 if (IS_PTR (rtype) && IS_ITEMP (right)
3356 && right->isaddr && checkType (rtype->next, ltype) == 1)
3358 right = geniCodeRValue (right, TRUE);
3362 right = geniCodeRValue (right, FALSE);
3365 geniCodeAssign (left,
3366 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3372 geniCodeAssign (left,
3373 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3375 geniCodeRValue (right, FALSE)), 0);
3378 geniCodeAssign (left,
3379 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3381 geniCodeRValue (right, FALSE)), 0);
3384 geniCodeAssign (left,
3385 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3387 geniCodeRValue (right, FALSE),
3389 operandType (left)), 0);
3392 geniCodeAssign (left,
3393 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3395 geniCodeRValue (right, FALSE),
3397 operandType (left)), 0);
3400 geniCodeAssign (left,
3401 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3403 geniCodeRValue (right, FALSE),
3405 operandType (left)), 0);
3407 return geniCodeRValue (right, FALSE);
3410 return geniCodeCall (ast2iCode (tree->left),
3413 geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
3414 return ast2iCode (tree->right);
3417 geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
3418 return ast2iCode (tree->right);
3421 geniCodeFunctionBody (tree);
3425 geniCodeReturn (right);
3433 geniCodeSwitch (tree);
3437 geniCodeInline (tree);
3444 /*-----------------------------------------------------------------*/
3445 /* reverseICChain - gets from the list and creates a linkedlist */
3446 /*-----------------------------------------------------------------*/
3453 while ((loop = getSet (&iCodeChain)))
3465 /*-----------------------------------------------------------------*/
3466 /* iCodeFromAst - given an ast will convert it to iCode */
3467 /*-----------------------------------------------------------------*/
3469 iCodeFromAst (ast * tree)
3471 returnLabel = newiTempLabel ("_return");
3472 entryLabel = newiTempLabel ("_entry");
3474 return reverseiCChain ();