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;
582 nic->parmBytes = ic->parmBytes;
584 /* deal with the special cases first */
588 IC_COND (nic) = operandFromOperand (IC_COND (ic));
589 IC_TRUE (nic) = IC_TRUE (ic);
590 IC_FALSE (nic) = IC_FALSE (ic);
594 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
595 IC_JTLABELS (nic) = IC_JTLABELS (ic);
600 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
601 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
602 IC_ARGS (nic) = IC_ARGS (ic);
606 IC_INLINE (nic) = IC_INLINE (ic);
610 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
611 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
612 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
618 /*-----------------------------------------------------------------*/
619 /* getTableEntry - gets the table entry for the given operator */
620 /*-----------------------------------------------------------------*/
622 getTableEntry (int oper)
626 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
627 if (oper == codeTable[i].icode)
628 return &codeTable[i];
633 /*-----------------------------------------------------------------*/
634 /* newiTempOperand - new intermediate temp operand */
635 /*-----------------------------------------------------------------*/
637 newiTempOperand (sym_link * type, char throwType)
640 operand *op = newOperand ();
644 itmp = newiTemp (NULL);
646 etype = getSpec (type);
648 if (IS_LITERAL (etype))
651 /* copy the type information */
653 itmp->etype = getSpec (itmp->type = (throwType ? type :
654 copyLinkChain (type)));
655 if (IS_LITERAL (itmp->etype))
657 SPEC_SCLS (itmp->etype) = S_REGISTER;
658 SPEC_OCLS (itmp->etype) = reg;
661 op->operand.symOperand = itmp;
662 op->key = itmp->key = ++operandKey;
666 /*-----------------------------------------------------------------*/
667 /* operandType - returns the type chain for an operand */
668 /*-----------------------------------------------------------------*/
670 operandType (operand * op)
672 /* depending on type of operand */
677 return op->operand.valOperand->type;
680 return op->operand.symOperand->type;
683 return op->operand.typeOperand;
685 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
686 " operand type not known ");
687 assert (0); /* should never come here */
688 /* Just to keep the compiler happy */
689 return (sym_link *) 0;
693 /*-----------------------------------------------------------------*/
694 /* isParamterToCall - will return 1 if op is a parameter to args */
695 /*-----------------------------------------------------------------*/
697 isParameterToCall (value * args, operand * op)
704 isSymbolEqual (op->operand.symOperand, tval->sym))
711 /*-----------------------------------------------------------------*/
712 /* isOperandGlobal - return 1 if operand is a global variable */
713 /*-----------------------------------------------------------------*/
715 isOperandGlobal (operand * op)
723 if (op->type == SYMBOL &&
724 (op->operand.symOperand->level == 0 ||
725 IS_STATIC (op->operand.symOperand->etype) ||
726 IS_EXTERN (op->operand.symOperand->etype))
733 /*-----------------------------------------------------------------*/
734 /* isOperandVolatile - return 1 if the operand is volatile */
735 /*-----------------------------------------------------------------*/
737 isOperandVolatile (operand * op, bool chkTemp)
742 if (IS_ITEMP (op) && !chkTemp)
745 opetype = getSpec (optype = operandType (op));
747 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
750 if (IS_VOLATILE (opetype))
755 /*-----------------------------------------------------------------*/
756 /* isOperandLiteral - returns 1 if an operand contains a literal */
757 /*-----------------------------------------------------------------*/
759 isOperandLiteral (operand * op)
766 opetype = getSpec (operandType (op));
768 if (IS_LITERAL (opetype))
773 /*-----------------------------------------------------------------*/
774 /* isOperandInFarSpace - will return true if operand is in farSpace */
775 /*-----------------------------------------------------------------*/
777 isOperandInFarSpace (operand * op)
787 if (!IS_TRUE_SYMOP (op))
790 etype = SPIL_LOC (op)->etype;
796 etype = getSpec (operandType (op));
798 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
801 /*-----------------------------------------------------------------*/
802 /* isOperandOnStack - will return true if operand is on stack */
803 /*-----------------------------------------------------------------*/
805 isOperandOnStack (operand * op)
815 etype = getSpec (operandType (op));
817 return ((IN_STACK (etype)) ? TRUE : FALSE);
820 /*-----------------------------------------------------------------*/
821 /* operandLitValue - literal value of an operand */
822 /*-----------------------------------------------------------------*/
824 operandLitValue (operand * op)
826 assert (isOperandLiteral (op));
828 return floatFromVal (op->operand.valOperand);
831 /*-----------------------------------------------------------------*/
832 /* operandOperation - perforoms operations on operands */
833 /*-----------------------------------------------------------------*/
835 operandOperation (operand * left, operand * right,
836 int op, sym_link * type)
838 operand *retval = (operand *) 0;
840 assert (isOperandLiteral (left));
842 assert (isOperandLiteral (right));
847 retval = operandFromValue (valCastLiteral (type,
848 operandLitValue (left) +
849 operandLitValue (right)));
852 retval = operandFromValue (valCastLiteral (type,
853 operandLitValue (left) -
854 operandLitValue (right)));
857 retval = operandFromValue (valCastLiteral (type,
858 operandLitValue (left) *
859 operandLitValue (right)));
862 if ((unsigned long) operandLitValue (right) == 0)
864 werror (E_DIVIDE_BY_ZERO);
869 retval = operandFromValue (valCastLiteral (type,
870 operandLitValue (left) /
871 operandLitValue (right)));
874 if ((unsigned long) operandLitValue (right) == 0)
876 werror (E_DIVIDE_BY_ZERO);
880 retval = operandFromLit ((unsigned long) operandLitValue (left) %
881 (unsigned long) operandLitValue (right));
884 retval = operandFromLit ((unsigned long) operandLitValue (left) <<
885 (unsigned long) operandLitValue (right));
888 retval = operandFromLit ((unsigned long) operandLitValue (left) >>
889 (unsigned long) operandLitValue (right));
892 retval = operandFromLit (operandLitValue (left) ==
893 operandLitValue (right));
896 retval = operandFromLit (operandLitValue (left) <
897 operandLitValue (right));
900 retval = operandFromLit (operandLitValue (left) <=
901 operandLitValue (right));
904 retval = operandFromLit (operandLitValue (left) !=
905 operandLitValue (right));
908 retval = operandFromLit (operandLitValue (left) >
909 operandLitValue (right));
912 retval = operandFromLit (operandLitValue (left) >=
913 operandLitValue (right));
916 retval = operandFromLit ((unsigned long) operandLitValue (left) &
917 (unsigned long) operandLitValue (right));
920 retval = operandFromLit ((unsigned long) operandLitValue (left) |
921 (unsigned long) operandLitValue (right));
924 retval = operandFromLit ((unsigned long) operandLitValue (left) ^
925 (unsigned long) operandLitValue (right));
928 retval = operandFromLit (operandLitValue (left) &&
929 operandLitValue (right));
932 retval = operandFromLit (operandLitValue (left) ||
933 operandLitValue (right));
937 long i = operandLitValue (left);
939 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
945 long i = operandLitValue (left);
947 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
953 retval = operandFromLit (-1 * operandLitValue (left));
957 retval = operandFromLit (~((long) operandLitValue (left)));
961 retval = operandFromLit (!operandLitValue (left));
965 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
966 " operandOperation invalid operator ");
974 /*-----------------------------------------------------------------*/
975 /* isOperandEqual - compares two operand & return 1 if they r = */
976 /*-----------------------------------------------------------------*/
978 isOperandEqual (operand * left, operand * right)
980 /* if the pointers are equal then they are equal */
984 /* if either of them null then false */
988 if (left->type != right->type)
991 if (IS_SYMOP (left) && IS_SYMOP (right))
992 return left->key == right->key;
994 /* if types are the same */
998 return isSymbolEqual (left->operand.symOperand,
999 right->operand.symOperand);
1001 return (floatFromVal (left->operand.valOperand) ==
1002 floatFromVal (right->operand.valOperand));
1004 if (checkType (left->operand.typeOperand,
1005 right->operand.typeOperand) == 1)
1012 /*-----------------------------------------------------------------*/
1013 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1014 /*-----------------------------------------------------------------*/
1016 isiCodeEqual (iCode * left, iCode * right)
1018 /* if the same pointer */
1022 /* if either of them null */
1023 if (!left || !right)
1026 /* if operand are the same */
1027 if (left->op == right->op)
1030 /* compare all the elements depending on type */
1031 if (left->op != IFX)
1033 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1035 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1041 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1043 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1045 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1053 /*-----------------------------------------------------------------*/
1054 /* newiTempFromOp - create a temp Operand with same attributes */
1055 /*-----------------------------------------------------------------*/
1057 newiTempFromOp (operand * op)
1067 nop = newiTempOperand (operandType (op), TRUE);
1068 nop->isaddr = op->isaddr;
1069 nop->isvolatile = op->isvolatile;
1070 nop->isGlobal = op->isGlobal;
1071 nop->isLiteral = op->isLiteral;
1072 nop->noSpilLoc = op->noSpilLoc;
1073 nop->usesDefs = op->usesDefs;
1074 nop->isParm = op->isParm;
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;
1102 nop->operand.symOperand = op->operand.symOperand;
1105 nop->operand.valOperand = op->operand.valOperand;
1108 nop->operand.typeOperand = op->operand.typeOperand;
1115 /*-----------------------------------------------------------------*/
1116 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1117 /*-----------------------------------------------------------------*/
1119 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1121 operand *nop = operandFromOperand (op);
1123 if (nop->type == SYMBOL)
1125 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1126 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1132 /*-----------------------------------------------------------------*/
1133 /* operandFromSymbol - creates an operand from a symbol */
1134 /*-----------------------------------------------------------------*/
1136 operandFromSymbol (symbol * sym)
1141 /* if the symbol's type is a literal */
1142 /* then it is an enumerator type */
1143 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1144 return operandFromValue (valFromType (sym->etype));
1147 sym->key = ++operandKey;
1149 /* if this an implicit variable, means struct/union */
1150 /* member so just return it */
1151 if (sym->implicit || IS_FUNC (sym->type))
1155 op->operand.symOperand = sym;
1157 op->isvolatile = isOperandVolatile (op, TRUE);
1158 op->isGlobal = isOperandGlobal (op);
1162 /* under the following conditions create a
1163 register equivalent for a local symbol */
1164 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1165 (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!IS_DS390_PORT)) &&
1166 options.stackAuto == 0)
1169 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1170 !IS_FUNC (sym->type) && /* not a function */
1171 !sym->_isparm && /* not a parameter */
1172 sym->level && /* is a local variable */
1173 !sym->addrtaken && /* whose address has not been taken */
1174 !sym->reqv && /* does not already have a register euivalence */
1175 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1176 !IS_STATIC (sym->etype) && /* and not declared static */
1177 !sym->islbl && /* not a label */
1178 ok && /* farspace check */
1179 !IS_BITVAR (sym->etype) /* not a bit variable */
1183 /* we will use it after all optimizations
1184 and before liveRange calculation */
1185 sym->reqv = newiTempOperand (sym->type, 0);
1186 sym->reqv->key = sym->key;
1187 OP_SYMBOL (sym->reqv)->key = sym->key;
1188 OP_SYMBOL (sym->reqv)->isreqv = 1;
1189 OP_SYMBOL (sym->reqv)->islocal = 1;
1190 SPIL_LOC (sym->reqv) = sym;
1193 if (!IS_AGGREGATE (sym->type))
1197 op->operand.symOperand = sym;
1200 op->isvolatile = isOperandVolatile (op, TRUE);
1201 op->isGlobal = isOperandGlobal (op);
1202 op->isPtr = IS_PTR (operandType (op));
1203 op->isParm = sym->_isparm;
1208 /* itemp = &[_symbol] */
1210 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1211 IC_LEFT (ic)->type = SYMBOL;
1212 IC_LEFT (ic)->operand.symOperand = sym;
1213 IC_LEFT (ic)->key = sym->key;
1214 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1215 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1216 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1219 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1220 if (IS_ARRAY (sym->type))
1222 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1223 IC_RESULT (ic)->isaddr = 0;
1226 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1228 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1232 return IC_RESULT (ic);
1235 /*-----------------------------------------------------------------*/
1236 /* operandFromValue - creates an operand from value */
1237 /*-----------------------------------------------------------------*/
1239 operandFromValue (value * val)
1243 /* if this is a symbol then do the symbol thing */
1245 return operandFromSymbol (val->sym);
1247 /* this is not a symbol */
1250 op->operand.valOperand = val;
1251 op->isLiteral = isOperandLiteral (op);
1255 /*-----------------------------------------------------------------*/
1256 /* operandFromLink - operand from typeChain */
1257 /*-----------------------------------------------------------------*/
1259 operandFromLink (sym_link * type)
1263 /* operand from sym_link */
1269 op->operand.typeOperand = copyLinkChain (type);
1273 /*-----------------------------------------------------------------*/
1274 /* operandFromLit - makes an operand from a literal value */
1275 /*-----------------------------------------------------------------*/
1277 operandFromLit (float i)
1279 return operandFromValue (valueFromLit (i));
1282 /*-----------------------------------------------------------------*/
1283 /* operandFromAst - creates an operand from an ast */
1284 /*-----------------------------------------------------------------*/
1286 operandFromAst (ast * tree)
1292 /* depending on type do */
1296 return ast2iCode (tree);
1300 return operandFromValue (tree->opval.val);
1304 return operandFromLink (tree->opval.lnk);
1308 /* Just to keep the comiler happy */
1309 return (operand *) 0;
1312 /*-----------------------------------------------------------------*/
1313 /* setOperandType - sets the operand's type to the given type */
1314 /*-----------------------------------------------------------------*/
1316 setOperandType (operand * op, sym_link * type)
1318 /* depending on the type of operand */
1323 op->operand.valOperand->etype =
1324 getSpec (op->operand.valOperand->type =
1325 copyLinkChain (type));
1329 if (op->operand.symOperand->isitmp)
1330 op->operand.symOperand->etype =
1331 getSpec (op->operand.symOperand->type =
1332 copyLinkChain (type));
1334 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1335 "attempt to modify type of source");
1339 op->operand.typeOperand = copyLinkChain (type);
1345 /*-----------------------------------------------------------------*/
1346 /* perform "usual unary conversions" */
1347 /*-----------------------------------------------------------------*/
1349 usualUnaryConversions (operand * op)
1351 if (IS_INTEGRAL (operandType (op)))
1353 if (getSize (operandType (op)) < INTSIZE)
1356 return geniCodeCast (INTTYPE, op, TRUE);
1362 /*-----------------------------------------------------------------*/
1363 /* perform "usual binary conversions" */
1364 /*-----------------------------------------------------------------*/
1366 usualBinaryConversions (operand ** op1, operand ** op2)
1368 if (!options.ANSIint)
1370 /* "Classic" SDCC behavior. */
1372 sym_link *rtype = operandType (*op2);
1373 sym_link *ltype = operandType (*op1);
1375 ctype = computeType (ltype, rtype);
1376 *op1 = geniCodeCast (ctype, *op1, TRUE);
1377 *op2 = geniCodeCast (ctype, *op2, TRUE);
1382 *op1 = usualUnaryConversions (*op1);
1383 *op2 = usualUnaryConversions (*op2);
1385 /* Try to make the two operands of the same type, following
1386 * the "usual binary conversions" promotion rules.
1388 * NB: floating point types are not yet properly handled; we
1389 * follow the "classic" behavior.
1392 if (IS_FLOAT (operandType (*op1)) || IS_FLOAT (operandType (*op2)))
1394 return newFloatLink ();
1397 if (!IS_INTEGRAL (operandType (*op1)) || !IS_INTEGRAL (operandType (*op2)))
1399 /* if either is not an integer type, we're done. */
1400 return copyLinkChain (operandType (*op1)); /* Punt! we should never get here. */
1403 /* If either is an unsigned long, make sure both are. */
1404 if (SPEC_USIGN (operandType (*op1)) && IS_LONG (operandType (*op1)))
1406 if (!SPEC_USIGN (operandType (*op2)) || !IS_LONG (operandType (*op2)))
1408 *op2 = geniCodeCast (ULONGTYPE, *op2, TRUE);
1410 return copyLinkChain (operandType (*op1));
1413 if (SPEC_USIGN (operandType (*op2)) && IS_LONG (operandType (*op2)))
1415 if (!SPEC_USIGN (operandType (*op1)) || !IS_LONG (operandType (*op1)))
1417 *op1 = geniCodeCast (ULONGTYPE, *op1, TRUE);
1419 return copyLinkChain (operandType (*op2));
1422 /* Next, if one is long and the other is int (signed or un),
1423 * cast both to long.
1425 * Note that because in our environment a long can hold all
1426 * the values of an unsigned int, the "long/unsigned int" pair
1427 * in the ANSI conversion table is unnecessary; this test
1428 * handles that case implicitly.
1430 if (IS_LONG (operandType (*op1)))
1432 /* NB: because of the unary conversions, op2 cannot
1433 * be smaller than int. Therefore, if it is not
1434 * long, it is a regular int.
1436 if (!IS_LONG (operandType (*op2)))
1438 *op2 = geniCodeCast (LONGTYPE, *op2, TRUE);
1440 return copyLinkChain (operandType (*op1));
1443 if (IS_LONG (operandType (*op2)))
1445 /* NB: because of the unary conversions, op2 cannot
1446 * be smaller than int. Therefore, if it is not
1447 * long, it is a regular int.
1449 if (!IS_LONG (operandType (*op1)))
1451 *op1 = geniCodeCast (LONGTYPE, *op1, TRUE);
1453 return copyLinkChain (operandType (*op2));
1456 /* All right, neither is long; they must both be integers.
1458 * Only remaining issue is signed vs. unsigned; if one is unsigned
1459 * and the other isn't, convert both to unsigned.
1461 if (SPEC_USIGN (operandType (*op1)))
1463 if (!SPEC_USIGN (operandType (*op2)))
1465 *op2 = geniCodeCast (UINTTYPE, *op2, TRUE);
1467 return copyLinkChain (operandType (*op1));
1470 if (SPEC_USIGN (operandType (*op2)))
1472 if (!SPEC_USIGN (operandType (*op1)))
1474 *op1 = geniCodeCast (UINTTYPE, *op1, TRUE);
1476 return copyLinkChain (operandType (*op2));
1480 return copyLinkChain (operandType (*op1));
1484 /*-----------------------------------------------------------------*/
1485 /* geniCodeValueAtAddress - generate intermeditate code for value */
1487 /*-----------------------------------------------------------------*/
1489 geniCodeRValue (operand * op, bool force)
1492 sym_link *type = operandType (op);
1493 sym_link *etype = getSpec (type);
1495 /* if this is an array & already */
1496 /* an address then return this */
1497 if (IS_AGGREGATE (type) ||
1498 (IS_PTR (type) && !force && !op->isaddr))
1499 return operandFromOperand (op);
1501 /* if this is not an address then must be */
1502 /* rvalue already so return this one */
1506 /* if this is not a temp symbol then */
1507 if (!IS_ITEMP (op) &&
1509 !IN_FARSPACE (SPEC_OCLS (etype)))
1511 op = operandFromOperand (op);
1516 if (IS_SPEC (type) &&
1517 IS_TRUE_SYMOP (op) &&
1518 (!IN_FARSPACE (SPEC_OCLS (etype)) || IS_DS390_PORT))
1520 op = operandFromOperand (op);
1525 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1526 if (IS_PTR (type) && op->isaddr && force)
1529 type = copyLinkChain (type);
1531 IC_RESULT (ic) = newiTempOperand (type, 1);
1532 IC_RESULT (ic)->isaddr = 0;
1534 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1536 /* if the right is a symbol */
1537 if (op->type == SYMBOL)
1538 IC_RESULT (ic)->operand.symOperand->args =
1539 op->operand.symOperand->args;
1542 return IC_RESULT (ic);
1545 /*-----------------------------------------------------------------*/
1546 /* geniCodeCast - changes the value from one type to another */
1547 /*-----------------------------------------------------------------*/
1549 geniCodeCast (sym_link * type, operand * op, bool implicit)
1553 sym_link *opetype = getSpec (optype = operandType (op));
1556 /* one of them has size zero then error */
1557 if (IS_VOID (optype))
1559 werror (E_CAST_ZERO);
1563 /* if the operand is already the desired type then do nothing */
1564 if (checkType (type, optype) == 1)
1567 /* if this is a literal then just change the type & return */
1568 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1569 return operandFromValue (valCastLiteral (type,
1570 operandLitValue (op)));
1572 /* if casting to some pointer type &&
1573 the destination is not a generic pointer
1574 then give a warning : (only for implicit casts) */
1575 if (IS_PTR (optype) && implicit &&
1576 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1579 werror (E_INCOMPAT_CAST);
1580 werror (E_CONTINUE, "from type '");
1581 printTypeChain (optype, stderr);
1582 fprintf (stderr, "' to type '");
1583 printTypeChain (type, stderr);
1584 fprintf (stderr, "'\n");
1587 /* if they are the same size create an assignment */
1588 if (getSize (type) == getSize (optype) &&
1589 !IS_BITFIELD (type) &&
1591 !IS_FLOAT (optype) &&
1592 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1593 (!IS_SPEC (type) && !IS_SPEC (optype))))
1596 ic = newiCode ('=', NULL, op);
1597 IC_RESULT (ic) = newiTempOperand (type, 0);
1598 SPIL_LOC (IC_RESULT (ic)) =
1599 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1600 IC_RESULT (ic)->isaddr = 0;
1604 ic = newiCode (CAST, operandFromLink (type),
1605 geniCodeRValue (op, FALSE));
1607 IC_RESULT (ic) = newiTempOperand (type, 0);
1610 /* preserve the storage class & output class */
1611 /* of the original variable */
1612 restype = getSpec (operandType (IC_RESULT (ic)));
1613 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1614 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1617 return IC_RESULT (ic);
1620 /*-----------------------------------------------------------------*/
1621 /* geniCodeLabel - will create a Label */
1622 /*-----------------------------------------------------------------*/
1624 geniCodeLabel (symbol * label)
1628 ic = newiCodeLabelGoto (LABEL, label);
1632 /*-----------------------------------------------------------------*/
1633 /* geniCodeGoto - will create a Goto */
1634 /*-----------------------------------------------------------------*/
1636 geniCodeGoto (symbol * label)
1640 ic = newiCodeLabelGoto (GOTO, label);
1644 /*-----------------------------------------------------------------*/
1645 /* geniCodeMultiply - gen intermediate code for multiplication */
1646 /*-----------------------------------------------------------------*/
1648 geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation,
1657 /* if they are both literal then we know the result */
1658 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1659 return operandFromValue (valMult (left->operand.valOperand,
1660 right->operand.valOperand));
1663 //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size
1664 if ((ptrSizeCalculation) && (1 == getSize (rtype)) &&
1665 (1 == getSize (ltype)))
1667 saveOption = options.ANSIint;
1668 options.ANSIint = 0;
1669 resType = usualBinaryConversions (&left, &right);
1670 ltype = operandType (left);
1671 rtype = operandType (right);
1672 SPEC_SHORT (getSpec (resType)) = 0;
1673 options.ANSIint = saveOption;
1676 resType = usualBinaryConversions (&left, &right);
1677 /* if (IS_DS390_PORT) { */
1678 /* jwk char*char=int
1679 Now be can use the 16bit result of "mul a,b" instead of explicit
1680 casts and support function calls as with --ansiint
1682 /* if ((IS_CHAR(letype) || IS_SHORT(letype)) && */
1683 /* (IS_CHAR(retype) || IS_SHORT(retype))) { */
1685 SPEC_NOUN(getSpec(resType))=V_INT;
1686 SPEC_SHORT(getSpec(resType))=0;
1691 /* if the right is a literal & power of 2 */
1692 /* then make it a left shift */
1693 /*If we are computing ptr size then normal multiplication */
1694 /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
1695 /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
1696 if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
1697 !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
1698 (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
1700 if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)))
1702 /* LEFT_OP need same size for left and result, */
1703 left = geniCodeCast (resType, left, TRUE);
1704 ltype = operandType (left);
1706 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1710 ic = newiCode ('*', left, right); /* normal multiplication */
1711 /* if the size left or right > 1 then support routine */
1712 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1716 IC_RESULT (ic) = newiTempOperand (resType, 1);
1719 return IC_RESULT (ic);
1722 /*-----------------------------------------------------------------*/
1723 /* geniCodeDivision - gen intermediate code for division */
1724 /*-----------------------------------------------------------------*/
1726 geniCodeDivision (operand * left, operand * right)
1731 sym_link *rtype = operandType (right);
1732 sym_link *retype = getSpec (rtype);
1733 sym_link *ltype = operandType (left);
1734 sym_link *letype = getSpec (ltype);
1736 resType = usualBinaryConversions (&left, &right);
1738 /* if the right is a literal & power of 2 */
1739 /* then make it a right shift */
1740 if (IS_LITERAL (retype) &&
1741 !IS_FLOAT (letype) &&
1742 (p2 = powof2 ((unsigned long)
1743 floatFromVal (right->operand.valOperand))))
1744 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1747 ic = newiCode ('/', left, right); /* normal division */
1748 /* if the size left or right > 1 then support routine */
1749 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1752 IC_RESULT (ic) = newiTempOperand (resType, 0);
1755 return IC_RESULT (ic);
1757 /*-----------------------------------------------------------------*/
1758 /* geniCodeModulus - gen intermediate code for modulus */
1759 /*-----------------------------------------------------------------*/
1761 geniCodeModulus (operand * left, operand * right)
1767 /* if they are both literal then we know the result */
1768 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1769 return operandFromValue (valMod (left->operand.valOperand,
1770 right->operand.valOperand));
1772 resType = usualBinaryConversions (&left, &right);
1774 /* now they are the same size */
1775 ic = newiCode ('%', left, right);
1777 /* if the size left or right > 1 then support routine */
1778 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1780 IC_RESULT (ic) = newiTempOperand (resType, 0);
1783 return IC_RESULT (ic);
1786 /*-----------------------------------------------------------------*/
1787 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1788 /*-----------------------------------------------------------------*/
1790 geniCodePtrPtrSubtract (operand * left, operand * right)
1796 /* if they are both literals then */
1797 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1799 result = operandFromValue (valMinus (left->operand.valOperand,
1800 right->operand.valOperand));
1804 ic = newiCode ('-', left, right);
1806 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1810 return geniCodeDivision (result,
1811 operandFromLit (getSize (ltype->next)));
1814 /*-----------------------------------------------------------------*/
1815 /* geniCodeSubtract - generates code for subtraction */
1816 /*-----------------------------------------------------------------*/
1818 geniCodeSubtract (operand * left, operand * right)
1825 /* if they both pointers then */
1826 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1827 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1828 return geniCodePtrPtrSubtract (left, right);
1830 /* if they are both literal then we know the result */
1831 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1832 && left->isLiteral && right->isLiteral)
1833 return operandFromValue (valMinus (left->operand.valOperand,
1834 right->operand.valOperand));
1836 /* if left is an array or pointer */
1837 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1839 isarray = left->isaddr;
1840 right = geniCodeMultiply (right,
1841 operandFromLit (getSize (ltype->next)), TRUE, FALSE);
1842 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1845 { /* make them the same size */
1846 resType = usualBinaryConversions (&left, &right);
1849 ic = newiCode ('-', left, right);
1851 IC_RESULT (ic) = newiTempOperand (resType, 1);
1852 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1854 /* if left or right is a float */
1855 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1859 return IC_RESULT (ic);
1862 /*-----------------------------------------------------------------*/
1863 /* geniCodeAdd - generates iCode for addition */
1864 /*-----------------------------------------------------------------*/
1866 geniCodeAdd (operand * left, operand * right)
1874 /* if left is an array then array access */
1875 if (IS_ARRAY (ltype))
1876 return geniCodeArray (left, right);
1878 /* if the right side is LITERAL zero */
1879 /* return the left side */
1880 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1883 /* if left is literal zero return right */
1884 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1887 /* if left is an array or pointer then size */
1891 isarray = left->isaddr;
1893 operandFromLit (getSize (ltype->next));
1895 right = geniCodeMultiply (right, size, (getSize (ltype) != 1),FALSE);
1897 resType = copyLinkChain (ltype);
1900 { /* make them the same size */
1901 resType = usualBinaryConversions (&left, &right);
1904 /* if they are both literals then we know */
1905 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1906 && left->isLiteral && right->isLiteral)
1907 return operandFromValue (valPlus (valFromType (letype),
1908 valFromType (retype)));
1910 ic = newiCode ('+', left, right);
1912 IC_RESULT (ic) = newiTempOperand (resType, 1);
1913 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1915 /* if left or right is a float then support
1917 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1922 return IC_RESULT (ic);
1926 /*-----------------------------------------------------------------*/
1927 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1928 /*-----------------------------------------------------------------*/
1930 aggrToPtr (sym_link * type, bool force)
1936 if (IS_PTR (type) && !force)
1939 etype = getSpec (type);
1943 /* if the output class is generic */
1944 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1945 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1947 /* if the variable was declared a constant */
1948 /* then the pointer points to a constant */
1949 if (IS_CONSTANT (etype))
1950 DCL_PTR_CONST (ptype) = 1;
1952 /* the variable was volatile then pointer to volatile */
1953 if (IS_VOLATILE (etype))
1954 DCL_PTR_VOLATILE (ptype) = 1;
1958 /*-----------------------------------------------------------------*/
1959 /* geniCodeArray2Ptr - array to pointer */
1960 /*-----------------------------------------------------------------*/
1962 geniCodeArray2Ptr (operand * op)
1964 sym_link *optype = operandType (op);
1965 sym_link *opetype = getSpec (optype);
1967 /* set the pointer depending on the storage class */
1968 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1969 DCL_PTR_CONST (optype) = port->mem.code_ro;
1972 /* if the variable was declared a constant */
1973 /* then the pointer points to a constant */
1974 if (IS_CONSTANT (opetype))
1975 DCL_PTR_CONST (optype) = 1;
1977 /* the variable was volatile then pointer to volatile */
1978 if (IS_VOLATILE (opetype))
1979 DCL_PTR_VOLATILE (optype) = 1;
1985 /*-----------------------------------------------------------------*/
1986 /* geniCodeArray - array access */
1987 /*-----------------------------------------------------------------*/
1989 geniCodeArray (operand * left, operand * right)
1992 sym_link *ltype = operandType (left);
1996 if (IS_PTR (ltype->next) && left->isaddr)
1998 left = geniCodeRValue (left, FALSE);
2000 return geniCodeDerefPtr (geniCodeAdd (left, right));
2004 right = geniCodeMultiply (right,
2005 operandFromLit (getSize (ltype->next)), TRUE,FALSE);
2007 /* we can check for limits here */
2008 if (isOperandLiteral (right) &&
2011 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2013 werror (E_ARRAY_BOUND);
2014 right = operandFromLit (0);
2017 ic = newiCode ('+', left, right);
2019 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2020 !IS_AGGREGATE (ltype->next) &&
2021 !IS_PTR (ltype->next))
2022 ? ltype : ltype->next), 0);
2024 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2026 return IC_RESULT (ic);
2029 /*-----------------------------------------------------------------*/
2030 /* geniCodeStruct - generates intermediate code for structres */
2031 /*-----------------------------------------------------------------*/
2033 geniCodeStruct (operand * left, operand * right, bool islval)
2036 sym_link *type = operandType (left);
2037 sym_link *etype = getSpec (type);
2039 symbol *element = getStructElement (SPEC_STRUCT (etype),
2040 right->operand.symOperand);
2042 /* add the offset */
2043 ic = newiCode ('+', left, operandFromLit (element->offset));
2045 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2047 /* preserve the storage & output class of the struct */
2048 /* as well as the volatile attribute */
2049 retype = getSpec (operandType (IC_RESULT (ic)));
2050 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2051 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2052 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2054 if (IS_PTR (element->type))
2055 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2057 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2061 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2064 /*-----------------------------------------------------------------*/
2065 /* geniCodePostInc - generate int code for Post increment */
2066 /*-----------------------------------------------------------------*/
2068 geniCodePostInc (operand * op)
2072 sym_link *optype = operandType (op);
2074 operand *rv = (IS_ITEMP (op) ?
2075 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2077 sym_link *rvtype = operandType (rv);
2080 /* if this is not an address we have trouble */
2083 werror (E_LVALUE_REQUIRED, "++");
2087 rOp = newiTempOperand (rvtype, 0);
2093 geniCodeAssign (rOp, rv, 0);
2095 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2096 if (IS_FLOAT (rvtype))
2097 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2099 ic = newiCode ('+', rv, operandFromLit (size));
2101 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2104 geniCodeAssign (op, result, 0);
2110 /*-----------------------------------------------------------------*/
2111 /* geniCodePreInc - generate code for preIncrement */
2112 /*-----------------------------------------------------------------*/
2114 geniCodePreInc (operand * op)
2117 sym_link *optype = operandType (op);
2118 operand *rop = (IS_ITEMP (op) ?
2119 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2121 sym_link *roptype = operandType (rop);
2127 werror (E_LVALUE_REQUIRED, "++");
2132 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2133 if (IS_FLOAT (roptype))
2134 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2136 ic = newiCode ('+', rop, operandFromLit (size));
2137 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2141 return geniCodeAssign (op, result, 0);
2144 /*-----------------------------------------------------------------*/
2145 /* geniCodePostDec - generates code for Post decrement */
2146 /*-----------------------------------------------------------------*/
2148 geniCodePostDec (operand * op)
2152 sym_link *optype = operandType (op);
2154 operand *rv = (IS_ITEMP (op) ?
2155 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2157 sym_link *rvtype = operandType (rv);
2160 /* if this is not an address we have trouble */
2163 werror (E_LVALUE_REQUIRED, "++");
2167 rOp = newiTempOperand (rvtype, 0);
2173 geniCodeAssign (rOp, rv, 0);
2175 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2176 if (IS_FLOAT (rvtype))
2177 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2179 ic = newiCode ('-', rv, operandFromLit (size));
2181 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2184 geniCodeAssign (op, result, 0);
2190 /*-----------------------------------------------------------------*/
2191 /* geniCodePreDec - generate code for pre decrement */
2192 /*-----------------------------------------------------------------*/
2194 geniCodePreDec (operand * op)
2197 sym_link *optype = operandType (op);
2198 operand *rop = (IS_ITEMP (op) ?
2199 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2201 sym_link *roptype = operandType (rop);
2207 werror (E_LVALUE_REQUIRED, "++");
2212 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2213 if (IS_FLOAT (roptype))
2214 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2216 ic = newiCode ('-', rop, operandFromLit (size));
2217 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2221 return geniCodeAssign (op, result, 0);
2225 /*-----------------------------------------------------------------*/
2226 /* geniCodeBitwise - gen int code for bitWise operators */
2227 /*-----------------------------------------------------------------*/
2229 geniCodeBitwise (operand * left, operand * right,
2230 int oper, sym_link * resType)
2234 left = geniCodeCast (resType, left, TRUE);
2235 right = geniCodeCast (resType, right, TRUE);
2237 ic = newiCode (oper, left, right);
2238 IC_RESULT (ic) = newiTempOperand (resType, 0);
2241 return IC_RESULT (ic);
2244 /*-----------------------------------------------------------------*/
2245 /* geniCodeAddressOf - gens icode for '&' address of operator */
2246 /*-----------------------------------------------------------------*/
2248 geniCodeAddressOf (operand * op)
2252 sym_link *optype = operandType (op);
2253 sym_link *opetype = getSpec (optype);
2255 /* lvalue check already done in decorateType */
2256 /* this must be a lvalue */
2257 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2258 /* werror (E_LVALUE_REQUIRED,"&"); */
2263 p->class = DECLARATOR;
2265 /* set the pointer depending on the storage class */
2266 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2267 DCL_PTR_CONST (p) = port->mem.code_ro;
2269 /* make sure we preserve the const & volatile */
2270 if (IS_CONSTANT (opetype))
2271 DCL_PTR_CONST (p) = 1;
2273 if (IS_VOLATILE (opetype))
2274 DCL_PTR_VOLATILE (p) = 1;
2276 p->next = copyLinkChain (optype);
2278 /* if already a temp */
2281 setOperandType (op, p);
2286 /* other wise make this of the type coming in */
2287 ic = newiCode (ADDRESS_OF, op, NULL);
2288 IC_RESULT (ic) = newiTempOperand (p, 1);
2289 IC_RESULT (ic)->isaddr = 0;
2291 return IC_RESULT (ic);
2293 /*-----------------------------------------------------------------*/
2294 /* setOClass - sets the output class depending on the pointer type */
2295 /*-----------------------------------------------------------------*/
2297 setOClass (sym_link * ptr, sym_link * spec)
2299 switch (DCL_TYPE (ptr))
2302 SPEC_OCLS (spec) = data;
2306 SPEC_OCLS (spec) = generic;
2310 SPEC_OCLS (spec) = xdata;
2314 SPEC_OCLS (spec) = code;
2318 SPEC_OCLS (spec) = idata;
2322 SPEC_OCLS (spec) = xstack;
2326 SPEC_OCLS (spec) = eeprom;
2335 /*-----------------------------------------------------------------*/
2336 /* geniCodeDerefPtr - dereference pointer with '*' */
2337 /*-----------------------------------------------------------------*/
2339 geniCodeDerefPtr (operand * op)
2341 sym_link *rtype, *retype;
2342 sym_link *optype = operandType (op);
2344 /* if this is a pointer then generate the rvalue */
2345 if (IS_PTR (optype))
2347 if (IS_TRUE_SYMOP (op))
2350 op = geniCodeRValue (op, TRUE);
2353 op = geniCodeRValue (op, TRUE);
2356 /* now get rid of the pointer part */
2357 if (lvaluereq && IS_ITEMP (op))
2359 retype = getSpec (rtype = copyLinkChain (optype));
2363 retype = getSpec (rtype = copyLinkChain (optype->next));
2366 /* if this is a pointer then outputclass needs 2b updated */
2367 if (IS_PTR (optype))
2368 setOClass (optype, retype);
2370 op->isGptr = IS_GENPTR (optype);
2372 /* if the pointer was declared as a constant */
2373 /* then we cannot allow assignment to the derefed */
2374 if (IS_PTR_CONST (optype))
2375 SPEC_CONST (retype) = 1;
2377 op->isaddr = (IS_PTR (rtype) ||
2378 IS_STRUCT (rtype) ||
2384 op = geniCodeRValue (op, TRUE);
2386 setOperandType (op, rtype);
2391 /*-----------------------------------------------------------------*/
2392 /* geniCodeUnaryMinus - does a unary minus of the operand */
2393 /*-----------------------------------------------------------------*/
2395 geniCodeUnaryMinus (operand * op)
2398 sym_link *optype = operandType (op);
2400 if (IS_LITERAL (optype))
2401 return operandFromLit (-floatFromVal (op->operand.valOperand));
2403 ic = newiCode (UNARYMINUS, op, NULL);
2404 IC_RESULT (ic) = newiTempOperand (optype, 0);
2406 return IC_RESULT (ic);
2409 /*-----------------------------------------------------------------*/
2410 /* geniCodeLeftShift - gen i code for left shift */
2411 /*-----------------------------------------------------------------*/
2413 geniCodeLeftShift (operand * left, operand * right)
2418 /* Note that we don't use the usual binary conversions for the
2419 * shift operations, in accordance with our ANSI friends.
2421 if (options.ANSIint)
2423 right = usualUnaryConversions (right);
2424 left = usualUnaryConversions (left);
2427 ic = newiCode (LEFT_OP, left, right);
2428 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2430 return IC_RESULT (ic);
2433 /*-----------------------------------------------------------------*/
2434 /* geniCodeRightShift - gen i code for right shift */
2435 /*-----------------------------------------------------------------*/
2437 geniCodeRightShift (operand * left, operand * right)
2442 /* Note that we don't use the usual binary conversions for the
2443 * shift operations, in accordance with our ANSI friends.
2445 if (options.ANSIint)
2447 right = usualUnaryConversions (right);
2448 left = usualUnaryConversions (left);
2451 ic = newiCode (RIGHT_OP, left, right);
2452 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2454 return IC_RESULT (ic);
2457 #if defined(__BORLANDC__) || defined(_MSC_VER)
2458 #define LONG_LONG __int64
2460 #define LONG_LONG long long
2463 /*-----------------------------------------------------------------*/
2464 /* geniCodeLogic- logic code */
2465 /*-----------------------------------------------------------------*/
2467 geniCodeLogic (operand * left, operand * right, int op)
2471 sym_link *rtype = operandType (right);
2472 sym_link *ltype = operandType (left);
2474 /* left is integral type and right is literal then
2475 check if the literal value is within bounds */
2476 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2478 int nbits = bitsForType (ltype);
2479 long v = operandLitValue (right);
2481 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2482 werror (W_CONST_RANGE, " compare operation ");
2485 ctype = usualBinaryConversions (&left, &right);
2487 ic = newiCode (op, left, right);
2488 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2490 /* if comparing anything greater than one byte
2491 and not a '==' || '!=' || '&&' || '||' (these
2493 if (getSize (ctype) > 1 &&
2501 return IC_RESULT (ic);
2504 /*-----------------------------------------------------------------*/
2505 /* geniCodeUnary - for a a generic unary operation */
2506 /*-----------------------------------------------------------------*/
2508 geniCodeUnary (operand * op, int oper)
2510 iCode *ic = newiCode (oper, op, NULL);
2512 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2514 return IC_RESULT (ic);
2517 /*-----------------------------------------------------------------*/
2518 /* geniCodeConditional - geniCode for '?' ':' operation */
2519 /*-----------------------------------------------------------------*/
2521 geniCodeConditional (ast * tree)
2524 symbol *falseLabel = newiTempLabel (NULL);
2525 symbol *exitLabel = newiTempLabel (NULL);
2526 operand *cond = ast2iCode (tree->left);
2527 operand *true, *false, *result;
2529 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2533 true = ast2iCode (tree->right->left);
2535 /* move the value to a new Operand */
2536 result = newiTempOperand (operandType (true), 0);
2537 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2539 /* generate an unconditional goto */
2540 geniCodeGoto (exitLabel);
2542 /* now for the right side */
2543 geniCodeLabel (falseLabel);
2545 false = ast2iCode (tree->right->right);
2546 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2548 /* create the exit label */
2549 geniCodeLabel (exitLabel);
2554 /*-----------------------------------------------------------------*/
2555 /* geniCodeAssign - generate code for assignment */
2556 /*-----------------------------------------------------------------*/
2558 geniCodeAssign (operand * left, operand * right, int nosupdate)
2561 sym_link *ltype = operandType (left);
2562 sym_link *rtype = operandType (right);
2564 if (!left->isaddr && !IS_ITEMP (left))
2566 werror (E_LVALUE_REQUIRED, "assignment");
2570 /* left is integral type and right is literal then
2571 check if the literal value is within bounds */
2572 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2574 int nbits = bitsForType (ltype);
2575 long v = operandLitValue (right);
2577 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2578 werror (W_CONST_RANGE, " = operation");
2581 /* if the left & right type don't exactly match */
2582 /* if pointer set then make sure the check is
2583 done with the type & not the pointer */
2584 /* then cast rights type to left */
2586 /* first check the type for pointer assignement */
2587 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2588 checkType (ltype, rtype) < 0)
2590 if (checkType (ltype->next, rtype) < 0)
2591 right = geniCodeCast (ltype->next, right, TRUE);
2593 else if (checkType (ltype, rtype) < 0)
2594 right = geniCodeCast (ltype, right, TRUE);
2596 /* if left is a true symbol & ! volatile
2597 create an assignment to temporary for
2598 the right & then assign this temporary
2599 to the symbol this is SSA . isn't it simple
2600 and folks have published mountains of paper on it */
2601 if (IS_TRUE_SYMOP (left) &&
2602 !isOperandVolatile (left, FALSE) &&
2603 isOperandGlobal (left))
2607 if (IS_TRUE_SYMOP (right))
2608 sym = OP_SYMBOL (right);
2609 ic = newiCode ('=', NULL, right);
2610 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2611 SPIL_LOC (right) = sym;
2615 ic = newiCode ('=', NULL, right);
2616 IC_RESULT (ic) = left;
2619 /* if left isgptr flag is set then support
2620 routine will be required */
2624 ic->nosupdate = nosupdate;
2628 /*-----------------------------------------------------------------*/
2629 /* geniCodeSEParms - generate code for side effecting fcalls */
2630 /*-----------------------------------------------------------------*/
2632 geniCodeSEParms (ast * parms)
2637 if (parms->type == EX_OP && parms->opval.op == PARAM)
2639 geniCodeSEParms (parms->left);
2640 geniCodeSEParms (parms->right);
2644 /* hack don't like this but too lazy to think of
2646 if (IS_ADDRESS_OF_OP (parms))
2647 parms->left->lvalue = 1;
2649 if (IS_CAST_OP (parms) &&
2650 IS_PTR (parms->ftype) &&
2651 IS_ADDRESS_OF_OP (parms->right))
2652 parms->right->left->lvalue = 1;
2654 parms->opval.oprnd =
2655 geniCodeRValue (ast2iCode (parms), FALSE);
2657 parms->type = EX_OPERAND;
2660 /*-----------------------------------------------------------------*/
2661 /* geniCodeParms - generates parameters */
2662 /*-----------------------------------------------------------------*/
2664 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
2672 /* if this is a param node then do the left & right */
2673 if (parms->type == EX_OP && parms->opval.op == PARAM)
2675 geniCodeParms (parms->left, stack, fetype, func);
2676 geniCodeParms (parms->right, stack, fetype, func);
2680 /* get the parameter value */
2681 if (parms->type == EX_OPERAND)
2682 pval = parms->opval.oprnd;
2685 /* maybe this else should go away ?? */
2686 /* hack don't like this but too lazy to think of
2688 if (IS_ADDRESS_OF_OP (parms))
2689 parms->left->lvalue = 1;
2691 if (IS_CAST_OP (parms) &&
2692 IS_PTR (parms->ftype) &&
2693 IS_ADDRESS_OF_OP (parms->right))
2694 parms->right->left->lvalue = 1;
2696 pval = geniCodeRValue (ast2iCode (parms), FALSE);
2699 /* if register parm then make it a send */
2700 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2701 IS_REGPARM (parms->etype)) && !func->hasVargs)
2703 ic = newiCode (SEND, pval, NULL);
2708 /* now decide whether to push or assign */
2709 if (!(options.stackAuto || IS_RENT (fetype)))
2713 operand *top = operandFromSymbol (parms->argSym);
2714 geniCodeAssign (top, pval, 1);
2718 sym_link *p = operandType (pval);
2720 ic = newiCode (IPUSH, pval, NULL);
2722 /* update the stack adjustment */
2723 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2730 /*-----------------------------------------------------------------*/
2731 /* geniCodeCall - generates temp code for calling */
2732 /*-----------------------------------------------------------------*/
2734 geniCodeCall (operand * left, ast * parms)
2738 sym_link *type, *etype;
2741 /* take care of parameters with side-effecting
2742 function calls in them, this is required to take care
2743 of overlaying function parameters */
2744 geniCodeSEParms (parms);
2746 /* first the parameters */
2747 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
2749 /* now call : if symbol then pcall */
2750 if (IS_OP_POINTER (left))
2751 ic = newiCode (PCALL, left, NULL);
2753 ic = newiCode (CALL, left, NULL);
2755 IC_ARGS (ic) = left->operand.symOperand->args;
2756 type = copyLinkChain (operandType (left)->next);
2757 etype = getSpec (type);
2758 SPEC_EXTR (etype) = 0;
2759 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2763 /* stack adjustment after call */
2764 ic->parmBytes = stack;
2769 /*-----------------------------------------------------------------*/
2770 /* geniCodeReceive - generate intermediate code for "receive" */
2771 /*-----------------------------------------------------------------*/
2773 geniCodeReceive (value * args)
2775 /* for all arguments that are passed in registers */
2779 if (IS_REGPARM (args->etype))
2781 operand *opr = operandFromValue (args);
2783 symbol *sym = OP_SYMBOL (opr);
2786 /* we will use it after all optimizations
2787 and before liveRange calculation */
2788 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2791 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2792 options.stackAuto == 0 &&
2798 opl = newiTempOperand (args->type, 0);
2800 sym->reqv->key = sym->key;
2801 OP_SYMBOL (sym->reqv)->key = sym->key;
2802 OP_SYMBOL (sym->reqv)->isreqv = 1;
2803 OP_SYMBOL (sym->reqv)->islocal = 0;
2804 SPIL_LOC (sym->reqv) = sym;
2808 ic = newiCode (RECEIVE, NULL, NULL);
2809 currFunc->recvSize = getSize (sym->etype);
2810 IC_RESULT (ic) = opr;
2818 /*-----------------------------------------------------------------*/
2819 /* geniCodeFunctionBody - create the function body */
2820 /*-----------------------------------------------------------------*/
2822 geniCodeFunctionBody (ast * tree)
2829 /* reset the auto generation */
2835 func = ast2iCode (tree->left);
2836 fetype = getSpec (operandType (func));
2838 savelineno = lineno;
2839 lineno = OP_SYMBOL (func)->lineDef;
2840 /* create an entry label */
2841 geniCodeLabel (entryLabel);
2842 lineno = savelineno;
2844 /* create a proc icode */
2845 ic = newiCode (FUNCTION, func, NULL);
2846 /* if the function has parmas then */
2847 /* save the parameters information */
2848 ic->argLabel.args = tree->values.args;
2849 ic->lineno = OP_SYMBOL (func)->lineDef;
2853 /* for all parameters that are passed
2854 on registers add a "receive" */
2855 geniCodeReceive (tree->values.args);
2857 /* generate code for the body */
2858 ast2iCode (tree->right);
2860 /* create a label for return */
2861 geniCodeLabel (returnLabel);
2863 /* now generate the end proc */
2864 ic = newiCode (ENDFUNCTION, func, NULL);
2869 /*-----------------------------------------------------------------*/
2870 /* geniCodeReturn - gen icode for 'return' statement */
2871 /*-----------------------------------------------------------------*/
2873 geniCodeReturn (operand * op)
2877 /* if the operand is present force an rvalue */
2879 op = geniCodeRValue (op, FALSE);
2881 ic = newiCode (RETURN, op, NULL);
2885 /*-----------------------------------------------------------------*/
2886 /* geniCodeIfx - generates code for extended if statement */
2887 /*-----------------------------------------------------------------*/
2889 geniCodeIfx (ast * tree)
2892 operand *condition = ast2iCode (tree->left);
2895 /* if condition is null then exit */
2899 condition = geniCodeRValue (condition, FALSE);
2901 cetype = getSpec (operandType (condition));
2902 /* if the condition is a literal */
2903 if (IS_LITERAL (cetype))
2905 if (floatFromVal (condition->operand.valOperand))
2907 if (tree->trueLabel)
2908 geniCodeGoto (tree->trueLabel);
2914 if (tree->falseLabel)
2915 geniCodeGoto (tree->falseLabel);
2922 if (tree->trueLabel)
2924 ic = newiCodeCondition (condition,
2929 if (tree->falseLabel)
2930 geniCodeGoto (tree->falseLabel);
2934 ic = newiCodeCondition (condition,
2941 ast2iCode (tree->right);
2944 /*-----------------------------------------------------------------*/
2945 /* geniCodeJumpTable - tries to create a jump table for switch */
2946 /*-----------------------------------------------------------------*/
2948 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2950 int min = 0, max = 0, t, cnt = 0;
2957 if (!tree || !caseVals)
2960 /* the criteria for creating a jump table is */
2961 /* all integer numbers between the maximum & minimum must */
2962 /* be present , the maximum value should not exceed 255 */
2963 min = max = (int) floatFromVal (vch = caseVals);
2964 sprintf (buffer, "_case_%d_%d",
2965 tree->values.switchVals.swNum,
2967 addSet (&labels, newiTempLabel (buffer));
2969 /* if there is only one case value then no need */
2970 if (!(vch = vch->next))
2975 if (((t = (int) floatFromVal (vch)) - max) != 1)
2977 sprintf (buffer, "_case_%d_%d",
2978 tree->values.switchVals.swNum,
2980 addSet (&labels, newiTempLabel (buffer));
2986 /* if the number of case statements <= 2 then */
2987 /* it is not economical to create the jump table */
2988 /* since two compares are needed for boundary conditions */
2989 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2992 if (tree->values.switchVals.swDefault)
2993 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2995 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2997 falseLabel = newiTempLabel (buffer);
2999 /* so we can create a jumptable */
3000 /* first we rule out the boundary conditions */
3001 /* if only optimization says so */
3002 if (!optimize.noJTabBoundary)
3004 sym_link *cetype = getSpec (operandType (cond));
3005 /* no need to check the lower bound if
3006 the condition is unsigned & minimum value is zero */
3007 if (!(min == 0 && SPEC_USIGN (cetype)))
3009 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3010 ic = newiCodeCondition (boundary, falseLabel, NULL);
3014 /* now for upper bounds */
3015 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3016 ic = newiCodeCondition (boundary, falseLabel, NULL);
3020 /* if the min is not zero then we no make it zero */
3023 cond = geniCodeSubtract (cond, operandFromLit (min));
3024 setOperandType (cond, UCHARTYPE);
3027 /* now create the jumptable */
3028 ic = newiCode (JUMPTABLE, NULL, NULL);
3029 IC_JTCOND (ic) = cond;
3030 IC_JTLABELS (ic) = labels;
3035 /*-----------------------------------------------------------------*/
3036 /* geniCodeSwitch - changes a switch to a if statement */
3037 /*-----------------------------------------------------------------*/
3039 geniCodeSwitch (ast * tree)
3042 operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
3043 value *caseVals = tree->values.switchVals.swVals;
3044 symbol *trueLabel, *falseLabel;
3046 /* if we can make this a jump table */
3047 if (geniCodeJumpTable (cond, caseVals, tree))
3048 goto jumpTable; /* no need for the comparison */
3050 /* for the cases defined do */
3054 operand *compare = geniCodeLogic (cond,
3055 operandFromValue (caseVals),
3058 sprintf (buffer, "_case_%d_%d",
3059 tree->values.switchVals.swNum,
3060 (int) floatFromVal (caseVals));
3061 trueLabel = newiTempLabel (buffer);
3063 ic = newiCodeCondition (compare, trueLabel, NULL);
3065 caseVals = caseVals->next;
3070 /* if default is present then goto break else break */
3071 if (tree->values.switchVals.swDefault)
3072 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3074 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3076 falseLabel = newiTempLabel (buffer);
3077 geniCodeGoto (falseLabel);
3080 ast2iCode (tree->right);
3083 /*-----------------------------------------------------------------*/
3084 /* geniCodeInline - intermediate code for inline assembler */
3085 /*-----------------------------------------------------------------*/
3087 geniCodeInline (ast * tree)
3091 ic = newiCode (INLINEASM, NULL, NULL);
3092 IC_INLINE (ic) = tree->values.inlineasm;
3096 /*-----------------------------------------------------------------*/
3097 /* ast2iCode - creates an icodeList from an ast */
3098 /*-----------------------------------------------------------------*/
3100 ast2iCode (ast * tree)
3102 operand *left = NULL;
3103 operand *right = NULL;
3108 /* set the global variables for filename & line number */
3110 filename = tree->filename;
3112 lineno = tree->lineno;
3114 block = tree->block;
3116 scopeLevel = tree->level;
3118 if (tree->type == EX_VALUE)
3119 return operandFromValue (tree->opval.val);
3121 if (tree->type == EX_LINK)
3122 return operandFromLink (tree->opval.lnk);
3124 /* if we find a nullop */
3125 if (tree->type == EX_OP &&
3126 (tree->opval.op == NULLOP ||
3127 tree->opval.op == BLOCK))
3129 ast2iCode (tree->left);
3130 ast2iCode (tree->right);
3134 /* special cases for not evaluating */
3135 if (tree->opval.op != ':' &&
3136 tree->opval.op != '?' &&
3137 tree->opval.op != CALL &&
3138 tree->opval.op != IFX &&
3139 tree->opval.op != LABEL &&
3140 tree->opval.op != GOTO &&
3141 tree->opval.op != SWITCH &&
3142 tree->opval.op != FUNCTION &&
3143 tree->opval.op != INLINEASM)
3146 if (IS_ASSIGN_OP (tree->opval.op) ||
3147 IS_DEREF_OP (tree) ||
3148 (tree->opval.op == '&' && !tree->right) ||
3149 tree->opval.op == PTR_OP)
3152 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3153 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3155 int olvr = lvaluereq;
3157 left = operandFromAst (tree->left);
3158 lvaluereq = olvr - 1;
3162 left = operandFromAst (tree->left);
3165 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3166 left = geniCodeRValue (left, TRUE);
3170 left = operandFromAst (tree->left);
3172 if (tree->opval.op == INC_OP ||
3173 tree->opval.op == DEC_OP)
3176 right = operandFromAst (tree->right);
3181 right = operandFromAst (tree->right);
3185 /* now depending on the type of operand */
3186 /* this will be a biggy */
3187 switch (tree->opval.op)
3190 case '[': /* array operation */
3192 sym_link *ltype = operandType (left);
3193 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3194 right = geniCodeRValue (right, TRUE);
3197 return geniCodeArray (left, right);
3199 case '.': /* structure dereference */
3200 if (IS_PTR (operandType (left)))
3201 left = geniCodeRValue (left, TRUE);
3203 left = geniCodeRValue (left, FALSE);
3205 return geniCodeStruct (left, right, tree->lvalue);
3207 case PTR_OP: /* structure pointer dereference */
3210 pType = operandType (left);
3211 left = geniCodeRValue (left, TRUE);
3213 setOClass (pType, getSpec (operandType (left)));
3216 return geniCodeStruct (left, right, tree->lvalue);
3218 case INC_OP: /* increment operator */
3220 return geniCodePostInc (left);
3222 return geniCodePreInc (right);
3224 case DEC_OP: /* decrement operator */
3226 return geniCodePostDec (left);
3228 return geniCodePreDec (right);
3230 case '&': /* bitwise and or address of operator */
3232 { /* this is a bitwise operator */
3233 left = geniCodeRValue (left, FALSE);
3234 right = geniCodeRValue (right, FALSE);
3235 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3238 return geniCodeAddressOf (left);
3240 case '|': /* bitwise or & xor */
3242 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3243 geniCodeRValue (right, FALSE),
3248 return geniCodeDivision (geniCodeRValue (left, FALSE),
3249 geniCodeRValue (right, FALSE));
3252 return geniCodeModulus (geniCodeRValue (left, FALSE),
3253 geniCodeRValue (right, FALSE));
3256 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3257 geniCodeRValue (right, FALSE), FALSE,IS_INT(tree->ftype));
3259 return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
3263 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3264 geniCodeRValue (right, FALSE));
3266 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3270 return geniCodeAdd (geniCodeRValue (left, FALSE),
3271 geniCodeRValue (right, FALSE));
3273 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3276 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3277 geniCodeRValue (right, FALSE));
3280 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3281 geniCodeRValue (right, FALSE));
3283 return geniCodeCast (operandType (left),
3284 geniCodeRValue (right, FALSE), FALSE);
3290 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3294 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3295 setOperandType (op, UCHARTYPE);
3306 return geniCodeLogic (geniCodeRValue (left, FALSE),
3307 geniCodeRValue (right, FALSE),
3310 return geniCodeConditional (tree);
3313 return operandFromLit (getSize (tree->right->ftype));
3317 sym_link *rtype = operandType (right);
3318 sym_link *ltype = operandType (left);
3319 if (IS_PTR (rtype) && IS_ITEMP (right)
3320 && right->isaddr && checkType (rtype->next, ltype) == 1)
3321 right = geniCodeRValue (right, TRUE);
3323 right = geniCodeRValue (right, FALSE);
3325 geniCodeAssign (left, right, 0);
3330 geniCodeAssign (left,
3331 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3333 geniCodeRValue (right, FALSE), FALSE,FALSE), 0);
3337 geniCodeAssign (left,
3338 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3340 geniCodeRValue (right, FALSE)), 0);
3343 geniCodeAssign (left,
3344 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3346 geniCodeRValue (right, FALSE)), 0);
3349 sym_link *rtype = operandType (right);
3350 sym_link *ltype = operandType (left);
3351 if (IS_PTR (rtype) && IS_ITEMP (right)
3352 && right->isaddr && checkType (rtype->next, ltype) == 1)
3353 right = geniCodeRValue (right, TRUE);
3355 right = geniCodeRValue (right, FALSE);
3358 return geniCodeAssign (left,
3359 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3365 sym_link *rtype = operandType (right);
3366 sym_link *ltype = operandType (left);
3367 if (IS_PTR (rtype) && IS_ITEMP (right)
3368 && right->isaddr && checkType (rtype->next, ltype) == 1)
3370 right = geniCodeRValue (right, TRUE);
3374 right = geniCodeRValue (right, FALSE);
3377 geniCodeAssign (left,
3378 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3384 geniCodeAssign (left,
3385 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3387 geniCodeRValue (right, FALSE)), 0);
3390 geniCodeAssign (left,
3391 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3393 geniCodeRValue (right, FALSE)), 0);
3396 geniCodeAssign (left,
3397 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3399 geniCodeRValue (right, FALSE),
3401 operandType (left)), 0);
3404 geniCodeAssign (left,
3405 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3407 geniCodeRValue (right, FALSE),
3409 operandType (left)), 0);
3412 geniCodeAssign (left,
3413 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3415 geniCodeRValue (right, FALSE),
3417 operandType (left)), 0);
3419 return geniCodeRValue (right, FALSE);
3422 return geniCodeCall (ast2iCode (tree->left),
3425 geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
3426 return ast2iCode (tree->right);
3429 geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
3430 return ast2iCode (tree->right);
3433 geniCodeFunctionBody (tree);
3437 geniCodeReturn (right);
3445 geniCodeSwitch (tree);
3449 geniCodeInline (tree);
3456 /*-----------------------------------------------------------------*/
3457 /* reverseICChain - gets from the list and creates a linkedlist */
3458 /*-----------------------------------------------------------------*/
3465 while ((loop = getSet (&iCodeChain)))
3477 /*-----------------------------------------------------------------*/
3478 /* iCodeFromAst - given an ast will convert it to iCode */
3479 /*-----------------------------------------------------------------*/
3481 iCodeFromAst (ast * tree)
3483 returnLabel = newiTempLabel ("_return");
3484 entryLabel = newiTempLabel ("_entry");
3486 return reverseiCChain ();