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);
403 printiCChain(ic,stdout);
405 /*-----------------------------------------------------------------*/
406 /* printiCChain - prints intermediate code for humans */
407 /*-----------------------------------------------------------------*/
409 printiCChain (iCode * icChain, FILE * of)
416 for (loop = icChain; loop; loop = loop->next)
418 if ((icTab = getTableEntry (loop->op)))
420 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
421 loop->filename, loop->lineno,
422 loop->seq, loop->key, loop->depth, loop->supportRtn);
424 icTab->iCodePrint (of, loop, icTab->printName);
430 /*-----------------------------------------------------------------*/
431 /* newOperand - allocate, init & return a new iCode */
432 /*-----------------------------------------------------------------*/
438 op = Safe_calloc (1, sizeof (operand));
444 /*-----------------------------------------------------------------*/
445 /* newiCode - create and return a new iCode entry initialised */
446 /*-----------------------------------------------------------------*/
448 newiCode (int op, operand * left, operand * right)
452 ic = Safe_calloc (1, sizeof (iCode));
455 ic->filename = filename;
457 ic->level = scopeLevel;
459 ic->key = iCodeKey++;
461 IC_RIGHT (ic) = right;
466 /*-----------------------------------------------------------------*/
467 /* newiCode for conditional statements */
468 /*-----------------------------------------------------------------*/
470 newiCodeCondition (operand * condition,
476 ic = newiCode (IFX, NULL, NULL);
477 IC_COND (ic) = condition;
478 IC_TRUE (ic) = trueLabel;
479 IC_FALSE (ic) = falseLabel;
483 /*-----------------------------------------------------------------*/
484 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
485 /*-----------------------------------------------------------------*/
487 newiCodeLabelGoto (int op, symbol * label)
491 ic = newiCode (op, NULL, NULL);
493 ic->argLabel.label = label;
495 IC_RIGHT (ic) = NULL;
496 IC_RESULT (ic) = NULL;
500 /*-----------------------------------------------------------------*/
501 /* newiTemp - allocate & return a newItemp Variable */
502 /*-----------------------------------------------------------------*/
509 sprintf (buffer, "%s", s);
511 sprintf (buffer, "iTemp%d", iTempNum++);
512 itmp = newSymbol (buffer, 1);
513 strcpy (itmp->rname, itmp->name);
519 /*-----------------------------------------------------------------*/
520 /* newiTempLabel - creates a temp variable label */
521 /*-----------------------------------------------------------------*/
523 newiTempLabel (char *s)
527 /* check if this alredy exists */
528 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
532 itmplbl = newSymbol (s, 1);
535 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
536 itmplbl = newSymbol (buffer, 1);
541 itmplbl->key = labelKey++;
542 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
546 /*-----------------------------------------------------------------*/
547 /* newiTempPreheaderLabel - creates a new preheader label */
548 /*-----------------------------------------------------------------*/
550 newiTempPreheaderLabel ()
554 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
555 itmplbl = newSymbol (buffer, 1);
559 itmplbl->key = labelKey++;
560 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
565 /*-----------------------------------------------------------------*/
566 /* initiCode - initialises some iCode related stuff */
567 /*-----------------------------------------------------------------*/
574 /*-----------------------------------------------------------------*/
575 /* copyiCode - make a copy of the iCode given */
576 /*-----------------------------------------------------------------*/
578 copyiCode (iCode * ic)
580 iCode *nic = newiCode (ic->op, NULL, NULL);
582 nic->lineno = ic->lineno;
583 nic->filename = ic->filename;
584 nic->block = ic->block;
585 nic->level = ic->level;
586 nic->parmBytes = ic->parmBytes;
588 /* deal with the special cases first */
592 IC_COND (nic) = operandFromOperand (IC_COND (ic));
593 IC_TRUE (nic) = IC_TRUE (ic);
594 IC_FALSE (nic) = IC_FALSE (ic);
598 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
599 IC_JTLABELS (nic) = IC_JTLABELS (ic);
604 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
605 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
606 IC_ARGS (nic) = IC_ARGS (ic);
610 IC_INLINE (nic) = IC_INLINE (ic);
614 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
615 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
616 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
622 /*-----------------------------------------------------------------*/
623 /* getTableEntry - gets the table entry for the given operator */
624 /*-----------------------------------------------------------------*/
626 getTableEntry (int oper)
630 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
631 if (oper == codeTable[i].icode)
632 return &codeTable[i];
637 /*-----------------------------------------------------------------*/
638 /* newiTempOperand - new intermediate temp operand */
639 /*-----------------------------------------------------------------*/
641 newiTempOperand (sym_link * type, char throwType)
644 operand *op = newOperand ();
648 itmp = newiTemp (NULL);
650 etype = getSpec (type);
652 if (IS_LITERAL (etype))
655 /* copy the type information */
657 itmp->etype = getSpec (itmp->type = (throwType ? type :
658 copyLinkChain (type)));
659 if (IS_LITERAL (itmp->etype))
661 SPEC_SCLS (itmp->etype) = S_REGISTER;
662 SPEC_OCLS (itmp->etype) = reg;
665 op->operand.symOperand = itmp;
666 op->key = itmp->key = ++operandKey;
670 /*-----------------------------------------------------------------*/
671 /* operandType - returns the type chain for an operand */
672 /*-----------------------------------------------------------------*/
674 operandType (operand * op)
676 /* depending on type of operand */
681 return op->operand.valOperand->type;
684 return op->operand.symOperand->type;
687 return op->operand.typeOperand;
689 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
690 " operand type not known ");
691 assert (0); /* should never come here */
692 /* Just to keep the compiler happy */
693 return (sym_link *) 0;
697 /*-----------------------------------------------------------------*/
698 /* isParamterToCall - will return 1 if op is a parameter to args */
699 /*-----------------------------------------------------------------*/
701 isParameterToCall (value * args, operand * op)
708 isSymbolEqual (op->operand.symOperand, tval->sym))
715 /*-----------------------------------------------------------------*/
716 /* isOperandGlobal - return 1 if operand is a global variable */
717 /*-----------------------------------------------------------------*/
719 isOperandGlobal (operand * op)
727 if (op->type == SYMBOL &&
728 (op->operand.symOperand->level == 0 ||
729 IS_STATIC (op->operand.symOperand->etype) ||
730 IS_EXTERN (op->operand.symOperand->etype))
737 /*-----------------------------------------------------------------*/
738 /* isOperandVolatile - return 1 if the operand is volatile */
739 /*-----------------------------------------------------------------*/
741 isOperandVolatile (operand * op, bool chkTemp)
746 if (IS_ITEMP (op) && !chkTemp)
749 opetype = getSpec (optype = operandType (op));
751 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
754 if (IS_VOLATILE (opetype))
759 /*-----------------------------------------------------------------*/
760 /* isOperandLiteral - returns 1 if an operand contains a literal */
761 /*-----------------------------------------------------------------*/
763 isOperandLiteral (operand * op)
770 opetype = getSpec (operandType (op));
772 if (IS_LITERAL (opetype))
777 /*-----------------------------------------------------------------*/
778 /* isOperandInFarSpace - will return true if operand is in farSpace */
779 /*-----------------------------------------------------------------*/
781 isOperandInFarSpace (operand * op)
791 if (!IS_TRUE_SYMOP (op))
794 etype = SPIL_LOC (op)->etype;
800 etype = getSpec (operandType (op));
802 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
805 /*-----------------------------------------------------------------*/
806 /* isOperandOnStack - will return true if operand is on stack */
807 /*-----------------------------------------------------------------*/
809 isOperandOnStack (operand * op)
819 etype = getSpec (operandType (op));
821 return ((IN_STACK (etype)) ? TRUE : FALSE);
824 /*-----------------------------------------------------------------*/
825 /* operandLitValue - literal value of an operand */
826 /*-----------------------------------------------------------------*/
828 operandLitValue (operand * op)
830 assert (isOperandLiteral (op));
832 return floatFromVal (op->operand.valOperand);
835 /*-----------------------------------------------------------------*/
836 /* operandOperation - perforoms operations on operands */
837 /*-----------------------------------------------------------------*/
839 operandOperation (operand * left, operand * right,
840 int op, sym_link * type)
842 operand *retval = (operand *) 0;
844 assert (isOperandLiteral (left));
846 assert (isOperandLiteral (right));
851 retval = operandFromValue (valCastLiteral (type,
852 operandLitValue (left) +
853 operandLitValue (right)));
856 retval = operandFromValue (valCastLiteral (type,
857 operandLitValue (left) -
858 operandLitValue (right)));
861 retval = operandFromValue (valCastLiteral (type,
862 operandLitValue (left) *
863 operandLitValue (right)));
866 if ((unsigned long) operandLitValue (right) == 0)
868 werror (E_DIVIDE_BY_ZERO);
873 retval = operandFromValue (valCastLiteral (type,
874 operandLitValue (left) /
875 operandLitValue (right)));
878 if ((unsigned long) operandLitValue (right) == 0)
880 werror (E_DIVIDE_BY_ZERO);
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 ((unsigned long) operandLitValue (left) >>
893 (unsigned long) 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 (operandLitValue (left) >=
917 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 ((unsigned long) operandLitValue (left) ^
929 (unsigned long) operandLitValue (right));
932 retval = operandFromLit (operandLitValue (left) &&
933 operandLitValue (right));
936 retval = operandFromLit (operandLitValue (left) ||
937 operandLitValue (right));
941 long i = operandLitValue (left);
943 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
949 long i = operandLitValue (left);
951 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
957 retval = operandFromLit (-1 * operandLitValue (left));
961 retval = operandFromLit (~((long) operandLitValue (left)));
965 retval = operandFromLit (!operandLitValue (left));
969 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
970 " operandOperation invalid operator ");
978 /*-----------------------------------------------------------------*/
979 /* isOperandEqual - compares two operand & return 1 if they r = */
980 /*-----------------------------------------------------------------*/
982 isOperandEqual (operand * left, operand * right)
984 /* if the pointers are equal then they are equal */
988 /* if either of them null then false */
992 if (left->type != right->type)
995 if (IS_SYMOP (left) && IS_SYMOP (right))
996 return left->key == right->key;
998 /* if types are the same */
1002 return isSymbolEqual (left->operand.symOperand,
1003 right->operand.symOperand);
1005 return (floatFromVal (left->operand.valOperand) ==
1006 floatFromVal (right->operand.valOperand));
1008 if (checkType (left->operand.typeOperand,
1009 right->operand.typeOperand) == 1)
1016 /*-----------------------------------------------------------------*/
1017 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1018 /*-----------------------------------------------------------------*/
1020 isiCodeEqual (iCode * left, iCode * right)
1022 /* if the same pointer */
1026 /* if either of them null */
1027 if (!left || !right)
1030 /* if operand are the same */
1031 if (left->op == right->op)
1034 /* compare all the elements depending on type */
1035 if (left->op != IFX)
1037 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1039 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1045 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1047 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1049 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1057 /*-----------------------------------------------------------------*/
1058 /* newiTempFromOp - create a temp Operand with same attributes */
1059 /*-----------------------------------------------------------------*/
1061 newiTempFromOp (operand * op)
1071 nop = newiTempOperand (operandType (op), TRUE);
1072 nop->isaddr = op->isaddr;
1073 nop->isvolatile = op->isvolatile;
1074 nop->isGlobal = op->isGlobal;
1075 nop->isLiteral = op->isLiteral;
1076 nop->noSpilLoc = op->noSpilLoc;
1077 nop->usesDefs = op->usesDefs;
1078 nop->isParm = op->isParm;
1082 /*-----------------------------------------------------------------*/
1083 /* operand from operand - creates an operand holder for the type */
1084 /*-----------------------------------------------------------------*/
1086 operandFromOperand (operand * op)
1092 nop = newOperand ();
1093 nop->type = op->type;
1094 nop->isaddr = op->isaddr;
1096 nop->isvolatile = op->isvolatile;
1097 nop->isGlobal = op->isGlobal;
1098 nop->isLiteral = op->isLiteral;
1099 nop->noSpilLoc = op->noSpilLoc;
1100 nop->usesDefs = op->usesDefs;
1101 nop->isParm = op->isParm;
1106 nop->operand.symOperand = op->operand.symOperand;
1109 nop->operand.valOperand = op->operand.valOperand;
1112 nop->operand.typeOperand = op->operand.typeOperand;
1119 /*-----------------------------------------------------------------*/
1120 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1121 /*-----------------------------------------------------------------*/
1123 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1125 operand *nop = operandFromOperand (op);
1127 if (nop->type == SYMBOL)
1129 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1130 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1136 /*-----------------------------------------------------------------*/
1137 /* operandFromSymbol - creates an operand from a symbol */
1138 /*-----------------------------------------------------------------*/
1140 operandFromSymbol (symbol * sym)
1145 /* if the symbol's type is a literal */
1146 /* then it is an enumerator type */
1147 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1148 return operandFromValue (valFromType (sym->etype));
1151 sym->key = ++operandKey;
1153 /* if this an implicit variable, means struct/union */
1154 /* member so just return it */
1155 if (sym->implicit || IS_FUNC (sym->type))
1159 op->operand.symOperand = sym;
1161 op->isvolatile = isOperandVolatile (op, TRUE);
1162 op->isGlobal = isOperandGlobal (op);
1166 /* under the following conditions create a
1167 register equivalent for a local symbol */
1168 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1169 (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!IS_DS390_PORT)) &&
1170 options.stackAuto == 0)
1173 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1174 !IS_FUNC (sym->type) && /* not a function */
1175 !sym->_isparm && /* not a parameter */
1176 sym->level && /* is a local variable */
1177 !sym->addrtaken && /* whose address has not been taken */
1178 !sym->reqv && /* does not already have a register euivalence */
1179 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1180 !IS_STATIC (sym->etype) && /* and not declared static */
1181 !sym->islbl && /* not a label */
1182 ok && /* farspace check */
1183 !IS_BITVAR (sym->etype) /* not a bit variable */
1187 /* we will use it after all optimizations
1188 and before liveRange calculation */
1189 sym->reqv = newiTempOperand (sym->type, 0);
1190 sym->reqv->key = sym->key;
1191 OP_SYMBOL (sym->reqv)->key = sym->key;
1192 OP_SYMBOL (sym->reqv)->isreqv = 1;
1193 OP_SYMBOL (sym->reqv)->islocal = 1;
1194 SPIL_LOC (sym->reqv) = sym;
1197 if (!IS_AGGREGATE (sym->type))
1201 op->operand.symOperand = sym;
1204 op->isvolatile = isOperandVolatile (op, TRUE);
1205 op->isGlobal = isOperandGlobal (op);
1206 op->isPtr = IS_PTR (operandType (op));
1207 op->isParm = sym->_isparm;
1212 /* itemp = &[_symbol] */
1214 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1215 IC_LEFT (ic)->type = SYMBOL;
1216 IC_LEFT (ic)->operand.symOperand = sym;
1217 IC_LEFT (ic)->key = sym->key;
1218 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1219 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1220 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1223 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1224 if (IS_ARRAY (sym->type))
1226 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1227 IC_RESULT (ic)->isaddr = 0;
1230 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1232 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1236 return IC_RESULT (ic);
1239 /*-----------------------------------------------------------------*/
1240 /* operandFromValue - creates an operand from value */
1241 /*-----------------------------------------------------------------*/
1243 operandFromValue (value * val)
1247 /* if this is a symbol then do the symbol thing */
1249 return operandFromSymbol (val->sym);
1251 /* this is not a symbol */
1254 op->operand.valOperand = val;
1255 op->isLiteral = isOperandLiteral (op);
1259 /*-----------------------------------------------------------------*/
1260 /* operandFromLink - operand from typeChain */
1261 /*-----------------------------------------------------------------*/
1263 operandFromLink (sym_link * type)
1267 /* operand from sym_link */
1273 op->operand.typeOperand = copyLinkChain (type);
1277 /*-----------------------------------------------------------------*/
1278 /* operandFromLit - makes an operand from a literal value */
1279 /*-----------------------------------------------------------------*/
1281 operandFromLit (float i)
1283 return operandFromValue (valueFromLit (i));
1286 /*-----------------------------------------------------------------*/
1287 /* operandFromAst - creates an operand from an ast */
1288 /*-----------------------------------------------------------------*/
1290 operandFromAst (ast * tree)
1296 /* depending on type do */
1300 return ast2iCode (tree);
1304 return operandFromValue (tree->opval.val);
1308 return operandFromLink (tree->opval.lnk);
1312 /* Just to keep the comiler happy */
1313 return (operand *) 0;
1316 /*-----------------------------------------------------------------*/
1317 /* setOperandType - sets the operand's type to the given type */
1318 /*-----------------------------------------------------------------*/
1320 setOperandType (operand * op, sym_link * type)
1322 /* depending on the type of operand */
1327 op->operand.valOperand->etype =
1328 getSpec (op->operand.valOperand->type =
1329 copyLinkChain (type));
1333 if (op->operand.symOperand->isitmp)
1334 op->operand.symOperand->etype =
1335 getSpec (op->operand.symOperand->type =
1336 copyLinkChain (type));
1338 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1339 "attempt to modify type of source");
1343 op->operand.typeOperand = copyLinkChain (type);
1349 /*-----------------------------------------------------------------*/
1350 /* perform "usual unary conversions" */
1351 /*-----------------------------------------------------------------*/
1353 usualUnaryConversions (operand * op)
1355 if (IS_INTEGRAL (operandType (op)))
1357 if (getSize (operandType (op)) < INTSIZE)
1360 return geniCodeCast (INTTYPE, op, TRUE);
1366 /*-----------------------------------------------------------------*/
1367 /* perform "usual binary conversions" */
1368 /*-----------------------------------------------------------------*/
1370 usualBinaryConversions (operand ** op1, operand ** op2)
1372 if (!options.ANSIint)
1374 /* "Classic" SDCC behavior. */
1376 sym_link *rtype = operandType (*op2);
1377 sym_link *ltype = operandType (*op1);
1379 ctype = computeType (ltype, rtype);
1380 *op1 = geniCodeCast (ctype, *op1, TRUE);
1381 *op2 = geniCodeCast (ctype, *op2, TRUE);
1386 *op1 = usualUnaryConversions (*op1);
1387 *op2 = usualUnaryConversions (*op2);
1389 /* Try to make the two operands of the same type, following
1390 * the "usual binary conversions" promotion rules.
1392 * NB: floating point types are not yet properly handled; we
1393 * follow the "classic" behavior.
1396 if (IS_FLOAT (operandType (*op1)) || IS_FLOAT (operandType (*op2)))
1398 return newFloatLink ();
1401 if (!IS_INTEGRAL (operandType (*op1)) || !IS_INTEGRAL (operandType (*op2)))
1403 /* if either is not an integer type, we're done. */
1404 return copyLinkChain (operandType (*op1)); /* Punt! we should never get here. */
1407 /* If either is an unsigned long, make sure both are. */
1408 if (SPEC_USIGN (operandType (*op1)) && IS_LONG (operandType (*op1)))
1410 if (!SPEC_USIGN (operandType (*op2)) || !IS_LONG (operandType (*op2)))
1412 *op2 = geniCodeCast (ULONGTYPE, *op2, TRUE);
1414 return copyLinkChain (operandType (*op1));
1417 if (SPEC_USIGN (operandType (*op2)) && IS_LONG (operandType (*op2)))
1419 if (!SPEC_USIGN (operandType (*op1)) || !IS_LONG (operandType (*op1)))
1421 *op1 = geniCodeCast (ULONGTYPE, *op1, TRUE);
1423 return copyLinkChain (operandType (*op2));
1426 /* Next, if one is long and the other is int (signed or un),
1427 * cast both to long.
1429 * Note that because in our environment a long can hold all
1430 * the values of an unsigned int, the "long/unsigned int" pair
1431 * in the ANSI conversion table is unnecessary; this test
1432 * handles that case implicitly.
1434 if (IS_LONG (operandType (*op1)))
1436 /* NB: because of the unary conversions, op2 cannot
1437 * be smaller than int. Therefore, if it is not
1438 * long, it is a regular int.
1440 if (!IS_LONG (operandType (*op2)))
1442 *op2 = geniCodeCast (LONGTYPE, *op2, TRUE);
1444 return copyLinkChain (operandType (*op1));
1447 if (IS_LONG (operandType (*op2)))
1449 /* NB: because of the unary conversions, op2 cannot
1450 * be smaller than int. Therefore, if it is not
1451 * long, it is a regular int.
1453 if (!IS_LONG (operandType (*op1)))
1455 *op1 = geniCodeCast (LONGTYPE, *op1, TRUE);
1457 return copyLinkChain (operandType (*op2));
1460 /* All right, neither is long; they must both be integers.
1462 * Only remaining issue is signed vs. unsigned; if one is unsigned
1463 * and the other isn't, convert both to unsigned.
1465 if (SPEC_USIGN (operandType (*op1)))
1467 if (!SPEC_USIGN (operandType (*op2)))
1469 *op2 = geniCodeCast (UINTTYPE, *op2, TRUE);
1471 return copyLinkChain (operandType (*op1));
1474 if (SPEC_USIGN (operandType (*op2)))
1476 if (!SPEC_USIGN (operandType (*op1)))
1478 *op1 = geniCodeCast (UINTTYPE, *op1, TRUE);
1480 return copyLinkChain (operandType (*op2));
1484 return copyLinkChain (operandType (*op1));
1488 /*-----------------------------------------------------------------*/
1489 /* geniCodeValueAtAddress - generate intermeditate code for value */
1491 /*-----------------------------------------------------------------*/
1493 geniCodeRValue (operand * op, bool force)
1496 sym_link *type = operandType (op);
1497 sym_link *etype = getSpec (type);
1499 /* if this is an array & already */
1500 /* an address then return this */
1501 if (IS_AGGREGATE (type) ||
1502 (IS_PTR (type) && !force && !op->isaddr))
1503 return operandFromOperand (op);
1505 /* if this is not an address then must be */
1506 /* rvalue already so return this one */
1510 /* if this is not a temp symbol then */
1511 if (!IS_ITEMP (op) &&
1513 !IN_FARSPACE (SPEC_OCLS (etype)))
1515 op = operandFromOperand (op);
1520 if (IS_SPEC (type) &&
1521 IS_TRUE_SYMOP (op) &&
1522 (!IN_FARSPACE (SPEC_OCLS (etype)) || IS_DS390_PORT))
1524 op = operandFromOperand (op);
1529 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1530 if (IS_PTR (type) && op->isaddr && force)
1533 type = copyLinkChain (type);
1535 IC_RESULT (ic) = newiTempOperand (type, 1);
1536 IC_RESULT (ic)->isaddr = 0;
1538 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1540 /* if the right is a symbol */
1541 if (op->type == SYMBOL)
1542 IC_RESULT (ic)->operand.symOperand->args =
1543 op->operand.symOperand->args;
1546 return IC_RESULT (ic);
1549 /*-----------------------------------------------------------------*/
1550 /* geniCodeCast - changes the value from one type to another */
1551 /*-----------------------------------------------------------------*/
1553 geniCodeCast (sym_link * type, operand * op, bool implicit)
1557 sym_link *opetype = getSpec (optype = operandType (op));
1560 /* one of them has size zero then error */
1561 if (IS_VOID (optype))
1563 werror (E_CAST_ZERO);
1567 /* if the operand is already the desired type then do nothing */
1568 if (checkType (type, optype) == 1)
1571 /* if this is a literal then just change the type & return */
1572 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1573 return operandFromValue (valCastLiteral (type,
1574 operandLitValue (op)));
1576 /* if casting to some pointer type &&
1577 the destination is not a generic pointer
1578 then give a warning : (only for implicit casts) */
1579 if (IS_PTR (optype) && implicit &&
1580 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1583 werror (E_INCOMPAT_CAST);
1584 werror (E_CONTINUE, "from type '");
1585 printTypeChain (optype, stderr);
1586 fprintf (stderr, "' to type '");
1587 printTypeChain (type, stderr);
1588 fprintf (stderr, "'\n");
1591 /* if they are the same size create an assignment */
1592 if (getSize (type) == getSize (optype) &&
1593 !IS_BITFIELD (type) &&
1595 !IS_FLOAT (optype) &&
1596 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1597 (!IS_SPEC (type) && !IS_SPEC (optype))))
1600 ic = newiCode ('=', NULL, op);
1601 IC_RESULT (ic) = newiTempOperand (type, 0);
1602 SPIL_LOC (IC_RESULT (ic)) =
1603 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1604 IC_RESULT (ic)->isaddr = 0;
1608 ic = newiCode (CAST, operandFromLink (type),
1609 geniCodeRValue (op, FALSE));
1611 IC_RESULT (ic) = newiTempOperand (type, 0);
1614 /* preserve the storage class & output class */
1615 /* of the original variable */
1616 restype = getSpec (operandType (IC_RESULT (ic)));
1617 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1618 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1621 return IC_RESULT (ic);
1624 /*-----------------------------------------------------------------*/
1625 /* geniCodeLabel - will create a Label */
1626 /*-----------------------------------------------------------------*/
1628 geniCodeLabel (symbol * label)
1632 ic = newiCodeLabelGoto (LABEL, label);
1636 /*-----------------------------------------------------------------*/
1637 /* geniCodeGoto - will create a Goto */
1638 /*-----------------------------------------------------------------*/
1640 geniCodeGoto (symbol * label)
1644 ic = newiCodeLabelGoto (GOTO, label);
1648 /*-----------------------------------------------------------------*/
1649 /* geniCodeMultiply - gen intermediate code for multiplication */
1650 /*-----------------------------------------------------------------*/
1652 geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation,
1661 /* if they are both literal then we know the result */
1662 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1663 return operandFromValue (valMult (left->operand.valOperand,
1664 right->operand.valOperand));
1667 //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size
1668 if ((ptrSizeCalculation) && (1 == getSize (rtype)) &&
1669 (1 == getSize (ltype)))
1671 saveOption = options.ANSIint;
1672 options.ANSIint = 0;
1673 resType = usualBinaryConversions (&left, &right);
1674 ltype = operandType (left);
1675 rtype = operandType (right);
1676 SPEC_SHORT (getSpec (resType)) = 0;
1677 options.ANSIint = saveOption;
1680 resType = usualBinaryConversions (&left, &right);
1681 /* if (IS_DS390_PORT) { */
1682 /* jwk char*char=int
1683 Now be can use the 16bit result of "mul a,b" instead of explicit
1684 casts and support function calls as with --ansiint
1686 /* if ((IS_CHAR(letype) || IS_SHORT(letype)) && */
1687 /* (IS_CHAR(retype) || IS_SHORT(retype))) { */
1689 SPEC_NOUN(getSpec(resType))=V_INT;
1690 SPEC_SHORT(getSpec(resType))=0;
1695 /* if the right is a literal & power of 2 */
1696 /* then make it a left shift */
1697 /*If we are computing ptr size then normal multiplication */
1698 /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
1699 /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
1700 if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
1701 !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
1702 (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
1704 if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)))
1706 /* LEFT_OP need same size for left and result, */
1707 left = geniCodeCast (resType, left, TRUE);
1708 ltype = operandType (left);
1710 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1714 ic = newiCode ('*', left, right); /* normal multiplication */
1715 /* if the size left or right > 1 then support routine */
1716 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1720 IC_RESULT (ic) = newiTempOperand (resType, 1);
1723 return IC_RESULT (ic);
1726 /*-----------------------------------------------------------------*/
1727 /* geniCodeDivision - gen intermediate code for division */
1728 /*-----------------------------------------------------------------*/
1730 geniCodeDivision (operand * left, operand * right)
1735 sym_link *rtype = operandType (right);
1736 sym_link *retype = getSpec (rtype);
1737 sym_link *ltype = operandType (left);
1738 sym_link *letype = getSpec (ltype);
1740 resType = usualBinaryConversions (&left, &right);
1742 /* if the right is a literal & power of 2 */
1743 /* then make it a right shift */
1744 if (IS_LITERAL (retype) &&
1745 !IS_FLOAT (letype) &&
1746 (p2 = powof2 ((unsigned long)
1747 floatFromVal (right->operand.valOperand))))
1748 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1751 ic = newiCode ('/', left, right); /* normal division */
1752 /* if the size left or right > 1 then support routine */
1753 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1756 IC_RESULT (ic) = newiTempOperand (resType, 0);
1759 return IC_RESULT (ic);
1761 /*-----------------------------------------------------------------*/
1762 /* geniCodeModulus - gen intermediate code for modulus */
1763 /*-----------------------------------------------------------------*/
1765 geniCodeModulus (operand * left, operand * right)
1771 /* if they are both literal then we know the result */
1772 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1773 return operandFromValue (valMod (left->operand.valOperand,
1774 right->operand.valOperand));
1776 resType = usualBinaryConversions (&left, &right);
1778 /* now they are the same size */
1779 ic = newiCode ('%', left, right);
1781 /* if the size left or right > 1 then support routine */
1782 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1784 IC_RESULT (ic) = newiTempOperand (resType, 0);
1787 return IC_RESULT (ic);
1790 /*-----------------------------------------------------------------*/
1791 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1792 /*-----------------------------------------------------------------*/
1794 geniCodePtrPtrSubtract (operand * left, operand * right)
1800 /* if they are both literals then */
1801 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1803 result = operandFromValue (valMinus (left->operand.valOperand,
1804 right->operand.valOperand));
1808 ic = newiCode ('-', left, right);
1810 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1814 return geniCodeDivision (result,
1815 operandFromLit (getSize (ltype->next)));
1818 /*-----------------------------------------------------------------*/
1819 /* geniCodeSubtract - generates code for subtraction */
1820 /*-----------------------------------------------------------------*/
1822 geniCodeSubtract (operand * left, operand * right)
1829 /* if they both pointers then */
1830 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1831 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1832 return geniCodePtrPtrSubtract (left, right);
1834 /* if they are both literal then we know the result */
1835 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1836 && left->isLiteral && right->isLiteral)
1837 return operandFromValue (valMinus (left->operand.valOperand,
1838 right->operand.valOperand));
1840 /* if left is an array or pointer */
1841 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1843 isarray = left->isaddr;
1844 right = geniCodeMultiply (right,
1845 operandFromLit (getSize (ltype->next)), TRUE, FALSE);
1846 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1849 { /* make them the same size */
1850 resType = usualBinaryConversions (&left, &right);
1853 ic = newiCode ('-', left, right);
1855 IC_RESULT (ic) = newiTempOperand (resType, 1);
1856 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1858 /* if left or right is a float */
1859 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1863 return IC_RESULT (ic);
1866 /*-----------------------------------------------------------------*/
1867 /* geniCodeAdd - generates iCode for addition */
1868 /*-----------------------------------------------------------------*/
1870 geniCodeAdd (operand * left, operand * right)
1878 /* if left is an array then array access */
1879 if (IS_ARRAY (ltype))
1880 return geniCodeArray (left, right);
1882 /* if the right side is LITERAL zero */
1883 /* return the left side */
1884 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1887 /* if left is literal zero return right */
1888 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1891 /* if left is an array or pointer then size */
1895 isarray = left->isaddr;
1897 operandFromLit (getSize (ltype->next));
1899 right = geniCodeMultiply (right, size, (getSize (ltype) != 1),FALSE);
1901 resType = copyLinkChain (ltype);
1904 { /* make them the same size */
1905 resType = usualBinaryConversions (&left, &right);
1908 /* if they are both literals then we know */
1909 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1910 && left->isLiteral && right->isLiteral)
1911 return operandFromValue (valPlus (valFromType (letype),
1912 valFromType (retype)));
1914 ic = newiCode ('+', left, right);
1916 IC_RESULT (ic) = newiTempOperand (resType, 1);
1917 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1919 /* if left or right is a float then support
1921 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1926 return IC_RESULT (ic);
1930 /*-----------------------------------------------------------------*/
1931 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1932 /*-----------------------------------------------------------------*/
1934 aggrToPtr (sym_link * type, bool force)
1940 if (IS_PTR (type) && !force)
1943 etype = getSpec (type);
1947 /* if the output class is generic */
1948 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1949 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1951 /* if the variable was declared a constant */
1952 /* then the pointer points to a constant */
1953 if (IS_CONSTANT (etype))
1954 DCL_PTR_CONST (ptype) = 1;
1956 /* the variable was volatile then pointer to volatile */
1957 if (IS_VOLATILE (etype))
1958 DCL_PTR_VOLATILE (ptype) = 1;
1962 /*-----------------------------------------------------------------*/
1963 /* geniCodeArray2Ptr - array to pointer */
1964 /*-----------------------------------------------------------------*/
1966 geniCodeArray2Ptr (operand * op)
1968 sym_link *optype = operandType (op);
1969 sym_link *opetype = getSpec (optype);
1971 /* set the pointer depending on the storage class */
1972 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1973 DCL_PTR_CONST (optype) = port->mem.code_ro;
1976 /* if the variable was declared a constant */
1977 /* then the pointer points to a constant */
1978 if (IS_CONSTANT (opetype))
1979 DCL_PTR_CONST (optype) = 1;
1981 /* the variable was volatile then pointer to volatile */
1982 if (IS_VOLATILE (opetype))
1983 DCL_PTR_VOLATILE (optype) = 1;
1989 /*-----------------------------------------------------------------*/
1990 /* geniCodeArray - array access */
1991 /*-----------------------------------------------------------------*/
1993 geniCodeArray (operand * left, operand * right)
1996 sym_link *ltype = operandType (left);
2000 if (IS_PTR (ltype->next) && left->isaddr)
2002 left = geniCodeRValue (left, FALSE);
2004 return geniCodeDerefPtr (geniCodeAdd (left, right));
2008 right = geniCodeMultiply (right,
2009 operandFromLit (getSize (ltype->next)), TRUE,FALSE);
2011 /* we can check for limits here */
2012 if (isOperandLiteral (right) &&
2015 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2017 werror (E_ARRAY_BOUND);
2018 right = operandFromLit (0);
2021 ic = newiCode ('+', left, right);
2023 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2024 !IS_AGGREGATE (ltype->next) &&
2025 !IS_PTR (ltype->next))
2026 ? ltype : ltype->next), 0);
2028 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2030 return IC_RESULT (ic);
2033 /*-----------------------------------------------------------------*/
2034 /* geniCodeStruct - generates intermediate code for structres */
2035 /*-----------------------------------------------------------------*/
2037 geniCodeStruct (operand * left, operand * right, bool islval)
2040 sym_link *type = operandType (left);
2041 sym_link *etype = getSpec (type);
2043 symbol *element = getStructElement (SPEC_STRUCT (etype),
2044 right->operand.symOperand);
2046 /* add the offset */
2047 ic = newiCode ('+', left, operandFromLit (element->offset));
2049 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2051 /* preserve the storage & output class of the struct */
2052 /* as well as the volatile attribute */
2053 retype = getSpec (operandType (IC_RESULT (ic)));
2054 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2055 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2056 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2058 if (IS_PTR (element->type))
2059 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2061 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2065 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2068 /*-----------------------------------------------------------------*/
2069 /* geniCodePostInc - generate int code for Post increment */
2070 /*-----------------------------------------------------------------*/
2072 geniCodePostInc (operand * op)
2076 sym_link *optype = operandType (op);
2078 operand *rv = (IS_ITEMP (op) ?
2079 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2081 sym_link *rvtype = operandType (rv);
2084 /* if this is not an address we have trouble */
2087 werror (E_LVALUE_REQUIRED, "++");
2091 rOp = newiTempOperand (rvtype, 0);
2097 geniCodeAssign (rOp, rv, 0);
2099 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2100 if (IS_FLOAT (rvtype))
2101 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2103 ic = newiCode ('+', rv, operandFromLit (size));
2105 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2108 geniCodeAssign (op, result, 0);
2114 /*-----------------------------------------------------------------*/
2115 /* geniCodePreInc - generate code for preIncrement */
2116 /*-----------------------------------------------------------------*/
2118 geniCodePreInc (operand * op)
2121 sym_link *optype = operandType (op);
2122 operand *rop = (IS_ITEMP (op) ?
2123 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2125 sym_link *roptype = operandType (rop);
2131 werror (E_LVALUE_REQUIRED, "++");
2136 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2137 if (IS_FLOAT (roptype))
2138 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2140 ic = newiCode ('+', rop, operandFromLit (size));
2141 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2145 return geniCodeAssign (op, result, 0);
2148 /*-----------------------------------------------------------------*/
2149 /* geniCodePostDec - generates code for Post decrement */
2150 /*-----------------------------------------------------------------*/
2152 geniCodePostDec (operand * op)
2156 sym_link *optype = operandType (op);
2158 operand *rv = (IS_ITEMP (op) ?
2159 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2161 sym_link *rvtype = operandType (rv);
2164 /* if this is not an address we have trouble */
2167 werror (E_LVALUE_REQUIRED, "++");
2171 rOp = newiTempOperand (rvtype, 0);
2177 geniCodeAssign (rOp, rv, 0);
2179 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2180 if (IS_FLOAT (rvtype))
2181 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2183 ic = newiCode ('-', rv, operandFromLit (size));
2185 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2188 geniCodeAssign (op, result, 0);
2194 /*-----------------------------------------------------------------*/
2195 /* geniCodePreDec - generate code for pre decrement */
2196 /*-----------------------------------------------------------------*/
2198 geniCodePreDec (operand * op)
2201 sym_link *optype = operandType (op);
2202 operand *rop = (IS_ITEMP (op) ?
2203 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2205 sym_link *roptype = operandType (rop);
2211 werror (E_LVALUE_REQUIRED, "++");
2216 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2217 if (IS_FLOAT (roptype))
2218 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2220 ic = newiCode ('-', rop, operandFromLit (size));
2221 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2225 return geniCodeAssign (op, result, 0);
2229 /*-----------------------------------------------------------------*/
2230 /* geniCodeBitwise - gen int code for bitWise operators */
2231 /*-----------------------------------------------------------------*/
2233 geniCodeBitwise (operand * left, operand * right,
2234 int oper, sym_link * resType)
2238 left = geniCodeCast (resType, left, TRUE);
2239 right = geniCodeCast (resType, right, TRUE);
2241 ic = newiCode (oper, left, right);
2242 IC_RESULT (ic) = newiTempOperand (resType, 0);
2245 return IC_RESULT (ic);
2248 /*-----------------------------------------------------------------*/
2249 /* geniCodeAddressOf - gens icode for '&' address of operator */
2250 /*-----------------------------------------------------------------*/
2252 geniCodeAddressOf (operand * op)
2256 sym_link *optype = operandType (op);
2257 sym_link *opetype = getSpec (optype);
2259 /* lvalue check already done in decorateType */
2260 /* this must be a lvalue */
2261 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2262 /* werror (E_LVALUE_REQUIRED,"&"); */
2267 p->class = DECLARATOR;
2269 /* set the pointer depending on the storage class */
2270 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2271 DCL_PTR_CONST (p) = port->mem.code_ro;
2273 /* make sure we preserve the const & volatile */
2274 if (IS_CONSTANT (opetype))
2275 DCL_PTR_CONST (p) = 1;
2277 if (IS_VOLATILE (opetype))
2278 DCL_PTR_VOLATILE (p) = 1;
2280 p->next = copyLinkChain (optype);
2282 /* if already a temp */
2285 setOperandType (op, p);
2290 /* other wise make this of the type coming in */
2291 ic = newiCode (ADDRESS_OF, op, NULL);
2292 IC_RESULT (ic) = newiTempOperand (p, 1);
2293 IC_RESULT (ic)->isaddr = 0;
2295 return IC_RESULT (ic);
2297 /*-----------------------------------------------------------------*/
2298 /* setOClass - sets the output class depending on the pointer type */
2299 /*-----------------------------------------------------------------*/
2301 setOClass (sym_link * ptr, sym_link * spec)
2303 switch (DCL_TYPE (ptr))
2306 SPEC_OCLS (spec) = data;
2310 SPEC_OCLS (spec) = generic;
2314 SPEC_OCLS (spec) = xdata;
2318 SPEC_OCLS (spec) = code;
2322 SPEC_OCLS (spec) = idata;
2326 SPEC_OCLS (spec) = xstack;
2330 SPEC_OCLS (spec) = eeprom;
2339 /*-----------------------------------------------------------------*/
2340 /* geniCodeDerefPtr - dereference pointer with '*' */
2341 /*-----------------------------------------------------------------*/
2343 geniCodeDerefPtr (operand * op)
2345 sym_link *rtype, *retype;
2346 sym_link *optype = operandType (op);
2348 /* if this is a pointer then generate the rvalue */
2349 if (IS_PTR (optype))
2351 if (IS_TRUE_SYMOP (op))
2354 op = geniCodeRValue (op, TRUE);
2357 op = geniCodeRValue (op, TRUE);
2360 /* now get rid of the pointer part */
2361 if (lvaluereq && IS_ITEMP (op))
2363 retype = getSpec (rtype = copyLinkChain (optype));
2367 retype = getSpec (rtype = copyLinkChain (optype->next));
2370 /* if this is a pointer then outputclass needs 2b updated */
2371 if (IS_PTR (optype))
2372 setOClass (optype, retype);
2374 op->isGptr = IS_GENPTR (optype);
2376 /* if the pointer was declared as a constant */
2377 /* then we cannot allow assignment to the derefed */
2378 if (IS_PTR_CONST (optype))
2379 SPEC_CONST (retype) = 1;
2381 op->isaddr = (IS_PTR (rtype) ||
2382 IS_STRUCT (rtype) ||
2388 op = geniCodeRValue (op, TRUE);
2390 setOperandType (op, rtype);
2395 /*-----------------------------------------------------------------*/
2396 /* geniCodeUnaryMinus - does a unary minus of the operand */
2397 /*-----------------------------------------------------------------*/
2399 geniCodeUnaryMinus (operand * op)
2402 sym_link *optype = operandType (op);
2404 if (IS_LITERAL (optype))
2405 return operandFromLit (-floatFromVal (op->operand.valOperand));
2407 ic = newiCode (UNARYMINUS, op, NULL);
2408 IC_RESULT (ic) = newiTempOperand (optype, 0);
2410 return IC_RESULT (ic);
2413 /*-----------------------------------------------------------------*/
2414 /* geniCodeLeftShift - gen i code for left shift */
2415 /*-----------------------------------------------------------------*/
2417 geniCodeLeftShift (operand * left, operand * right)
2422 /* Note that we don't use the usual binary conversions for the
2423 * shift operations, in accordance with our ANSI friends.
2425 if (options.ANSIint)
2427 right = usualUnaryConversions (right);
2428 left = usualUnaryConversions (left);
2431 ic = newiCode (LEFT_OP, left, right);
2432 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2434 return IC_RESULT (ic);
2437 /*-----------------------------------------------------------------*/
2438 /* geniCodeRightShift - gen i code for right shift */
2439 /*-----------------------------------------------------------------*/
2441 geniCodeRightShift (operand * left, operand * right)
2446 /* Note that we don't use the usual binary conversions for the
2447 * shift operations, in accordance with our ANSI friends.
2449 if (options.ANSIint)
2451 right = usualUnaryConversions (right);
2452 left = usualUnaryConversions (left);
2455 ic = newiCode (RIGHT_OP, left, right);
2456 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2458 return IC_RESULT (ic);
2461 #if defined(__BORLANDC__) || defined(_MSC_VER)
2462 #define LONG_LONG __int64
2464 #define LONG_LONG long long
2467 /*-----------------------------------------------------------------*/
2468 /* geniCodeLogic- logic code */
2469 /*-----------------------------------------------------------------*/
2471 geniCodeLogic (operand * left, operand * right, int op)
2475 sym_link *rtype = operandType (right);
2476 sym_link *ltype = operandType (left);
2478 /* left is integral type and right is literal then
2479 check if the literal value is within bounds */
2480 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2482 int nbits = bitsForType (ltype);
2483 long v = operandLitValue (right);
2485 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2486 werror (W_CONST_RANGE, " compare operation ");
2489 ctype = usualBinaryConversions (&left, &right);
2491 ic = newiCode (op, left, right);
2492 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2494 /* if comparing anything greater than one byte
2495 and not a '==' || '!=' || '&&' || '||' (these
2497 if (getSize (ctype) > 1 &&
2505 return IC_RESULT (ic);
2508 /*-----------------------------------------------------------------*/
2509 /* geniCodeUnary - for a a generic unary operation */
2510 /*-----------------------------------------------------------------*/
2512 geniCodeUnary (operand * op, int oper)
2514 iCode *ic = newiCode (oper, op, NULL);
2516 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2518 return IC_RESULT (ic);
2521 /*-----------------------------------------------------------------*/
2522 /* geniCodeConditional - geniCode for '?' ':' operation */
2523 /*-----------------------------------------------------------------*/
2525 geniCodeConditional (ast * tree)
2528 symbol *falseLabel = newiTempLabel (NULL);
2529 symbol *exitLabel = newiTempLabel (NULL);
2530 operand *cond = ast2iCode (tree->left);
2531 operand *true, *false, *result;
2533 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2537 true = ast2iCode (tree->right->left);
2539 /* move the value to a new Operand */
2540 result = newiTempOperand (operandType (true), 0);
2541 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2543 /* generate an unconditional goto */
2544 geniCodeGoto (exitLabel);
2546 /* now for the right side */
2547 geniCodeLabel (falseLabel);
2549 false = ast2iCode (tree->right->right);
2550 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2552 /* create the exit label */
2553 geniCodeLabel (exitLabel);
2558 /*-----------------------------------------------------------------*/
2559 /* geniCodeAssign - generate code for assignment */
2560 /*-----------------------------------------------------------------*/
2562 geniCodeAssign (operand * left, operand * right, int nosupdate)
2565 sym_link *ltype = operandType (left);
2566 sym_link *rtype = operandType (right);
2568 if (!left->isaddr && !IS_ITEMP (left))
2570 werror (E_LVALUE_REQUIRED, "assignment");
2574 /* left is integral type and right is literal then
2575 check if the literal value is within bounds */
2576 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2578 int nbits = bitsForType (ltype);
2579 long v = operandLitValue (right);
2581 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2582 werror (W_CONST_RANGE, " = operation");
2585 /* if the left & right type don't exactly match */
2586 /* if pointer set then make sure the check is
2587 done with the type & not the pointer */
2588 /* then cast rights type to left */
2590 /* first check the type for pointer assignement */
2591 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2592 checkType (ltype, rtype) < 0)
2594 if (checkType (ltype->next, rtype) < 0)
2595 right = geniCodeCast (ltype->next, right, TRUE);
2597 else if (checkType (ltype, rtype) < 0)
2598 right = geniCodeCast (ltype, right, TRUE);
2600 /* if left is a true symbol & ! volatile
2601 create an assignment to temporary for
2602 the right & then assign this temporary
2603 to the symbol this is SSA . isn't it simple
2604 and folks have published mountains of paper on it */
2605 if (IS_TRUE_SYMOP (left) &&
2606 !isOperandVolatile (left, FALSE) &&
2607 isOperandGlobal (left))
2611 if (IS_TRUE_SYMOP (right))
2612 sym = OP_SYMBOL (right);
2613 ic = newiCode ('=', NULL, right);
2614 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2615 SPIL_LOC (right) = sym;
2619 ic = newiCode ('=', NULL, right);
2620 IC_RESULT (ic) = left;
2623 /* if left isgptr flag is set then support
2624 routine will be required */
2628 ic->nosupdate = nosupdate;
2632 /*-----------------------------------------------------------------*/
2633 /* geniCodeSEParms - generate code for side effecting fcalls */
2634 /*-----------------------------------------------------------------*/
2636 geniCodeSEParms (ast * parms)
2641 if (parms->type == EX_OP && parms->opval.op == PARAM)
2643 geniCodeSEParms (parms->left);
2644 geniCodeSEParms (parms->right);
2648 /* hack don't like this but too lazy to think of
2650 if (IS_ADDRESS_OF_OP (parms))
2651 parms->left->lvalue = 1;
2653 if (IS_CAST_OP (parms) &&
2654 IS_PTR (parms->ftype) &&
2655 IS_ADDRESS_OF_OP (parms->right))
2656 parms->right->left->lvalue = 1;
2658 parms->opval.oprnd =
2659 geniCodeRValue (ast2iCode (parms), FALSE);
2661 parms->type = EX_OPERAND;
2664 /*-----------------------------------------------------------------*/
2665 /* geniCodeParms - generates parameters */
2666 /*-----------------------------------------------------------------*/
2668 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
2676 /* if this is a param node then do the left & right */
2677 if (parms->type == EX_OP && parms->opval.op == PARAM)
2679 geniCodeParms (parms->left, stack, fetype, func);
2680 geniCodeParms (parms->right, stack, fetype, func);
2684 /* get the parameter value */
2685 if (parms->type == EX_OPERAND)
2686 pval = parms->opval.oprnd;
2689 /* maybe this else should go away ?? */
2690 /* hack don't like this but too lazy to think of
2692 if (IS_ADDRESS_OF_OP (parms))
2693 parms->left->lvalue = 1;
2695 if (IS_CAST_OP (parms) &&
2696 IS_PTR (parms->ftype) &&
2697 IS_ADDRESS_OF_OP (parms->right))
2698 parms->right->left->lvalue = 1;
2700 pval = geniCodeRValue (ast2iCode (parms), FALSE);
2703 /* if register parm then make it a send */
2704 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2705 IS_REGPARM (parms->etype)) && !func->hasVargs)
2707 ic = newiCode (SEND, pval, NULL);
2712 /* now decide whether to push or assign */
2713 if (!(options.stackAuto || IS_RENT (fetype)))
2717 operand *top = operandFromSymbol (parms->argSym);
2718 geniCodeAssign (top, pval, 1);
2722 sym_link *p = operandType (pval);
2724 ic = newiCode (IPUSH, pval, NULL);
2726 /* update the stack adjustment */
2727 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2734 /*-----------------------------------------------------------------*/
2735 /* geniCodeCall - generates temp code for calling */
2736 /*-----------------------------------------------------------------*/
2738 geniCodeCall (operand * left, ast * parms)
2742 sym_link *type, *etype;
2745 /* take care of parameters with side-effecting
2746 function calls in them, this is required to take care
2747 of overlaying function parameters */
2748 geniCodeSEParms (parms);
2750 /* first the parameters */
2751 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
2753 /* now call : if symbol then pcall */
2754 if (IS_OP_POINTER (left))
2755 ic = newiCode (PCALL, left, NULL);
2757 ic = newiCode (CALL, left, NULL);
2759 IC_ARGS (ic) = left->operand.symOperand->args;
2760 type = copyLinkChain (operandType (left)->next);
2761 etype = getSpec (type);
2762 SPEC_EXTR (etype) = 0;
2763 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2767 /* stack adjustment after call */
2768 ic->parmBytes = stack;
2773 /*-----------------------------------------------------------------*/
2774 /* geniCodeReceive - generate intermediate code for "receive" */
2775 /*-----------------------------------------------------------------*/
2777 geniCodeReceive (value * args)
2779 /* for all arguments that are passed in registers */
2783 if (IS_REGPARM (args->etype))
2785 operand *opr = operandFromValue (args);
2787 symbol *sym = OP_SYMBOL (opr);
2790 /* we will use it after all optimizations
2791 and before liveRange calculation */
2792 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2795 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2796 options.stackAuto == 0 &&
2802 opl = newiTempOperand (args->type, 0);
2804 sym->reqv->key = sym->key;
2805 OP_SYMBOL (sym->reqv)->key = sym->key;
2806 OP_SYMBOL (sym->reqv)->isreqv = 1;
2807 OP_SYMBOL (sym->reqv)->islocal = 0;
2808 SPIL_LOC (sym->reqv) = sym;
2812 ic = newiCode (RECEIVE, NULL, NULL);
2813 currFunc->recvSize = getSize (sym->etype);
2814 IC_RESULT (ic) = opr;
2822 /*-----------------------------------------------------------------*/
2823 /* geniCodeFunctionBody - create the function body */
2824 /*-----------------------------------------------------------------*/
2826 geniCodeFunctionBody (ast * tree)
2833 /* reset the auto generation */
2839 func = ast2iCode (tree->left);
2840 fetype = getSpec (operandType (func));
2842 savelineno = lineno;
2843 lineno = OP_SYMBOL (func)->lineDef;
2844 /* create an entry label */
2845 geniCodeLabel (entryLabel);
2846 lineno = savelineno;
2848 /* create a proc icode */
2849 ic = newiCode (FUNCTION, func, NULL);
2850 /* if the function has parmas then */
2851 /* save the parameters information */
2852 ic->argLabel.args = tree->values.args;
2853 ic->lineno = OP_SYMBOL (func)->lineDef;
2857 /* for all parameters that are passed
2858 on registers add a "receive" */
2859 geniCodeReceive (tree->values.args);
2861 /* generate code for the body */
2862 ast2iCode (tree->right);
2864 /* create a label for return */
2865 geniCodeLabel (returnLabel);
2867 /* now generate the end proc */
2868 ic = newiCode (ENDFUNCTION, func, NULL);
2873 /*-----------------------------------------------------------------*/
2874 /* geniCodeReturn - gen icode for 'return' statement */
2875 /*-----------------------------------------------------------------*/
2877 geniCodeReturn (operand * op)
2881 /* if the operand is present force an rvalue */
2883 op = geniCodeRValue (op, FALSE);
2885 ic = newiCode (RETURN, op, NULL);
2889 /*-----------------------------------------------------------------*/
2890 /* geniCodeIfx - generates code for extended if statement */
2891 /*-----------------------------------------------------------------*/
2893 geniCodeIfx (ast * tree)
2896 operand *condition = ast2iCode (tree->left);
2899 /* if condition is null then exit */
2903 condition = geniCodeRValue (condition, FALSE);
2905 cetype = getSpec (operandType (condition));
2906 /* if the condition is a literal */
2907 if (IS_LITERAL (cetype))
2909 if (floatFromVal (condition->operand.valOperand))
2911 if (tree->trueLabel)
2912 geniCodeGoto (tree->trueLabel);
2918 if (tree->falseLabel)
2919 geniCodeGoto (tree->falseLabel);
2926 if (tree->trueLabel)
2928 ic = newiCodeCondition (condition,
2933 if (tree->falseLabel)
2934 geniCodeGoto (tree->falseLabel);
2938 ic = newiCodeCondition (condition,
2945 ast2iCode (tree->right);
2948 /*-----------------------------------------------------------------*/
2949 /* geniCodeJumpTable - tries to create a jump table for switch */
2950 /*-----------------------------------------------------------------*/
2952 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2954 int min = 0, max = 0, t, cnt = 0;
2961 if (!tree || !caseVals)
2964 /* the criteria for creating a jump table is */
2965 /* all integer numbers between the maximum & minimum must */
2966 /* be present , the maximum value should not exceed 255 */
2967 min = max = (int) floatFromVal (vch = caseVals);
2968 sprintf (buffer, "_case_%d_%d",
2969 tree->values.switchVals.swNum,
2971 addSet (&labels, newiTempLabel (buffer));
2973 /* if there is only one case value then no need */
2974 if (!(vch = vch->next))
2979 if (((t = (int) floatFromVal (vch)) - max) != 1)
2981 sprintf (buffer, "_case_%d_%d",
2982 tree->values.switchVals.swNum,
2984 addSet (&labels, newiTempLabel (buffer));
2990 /* if the number of case statements <= 2 then */
2991 /* it is not economical to create the jump table */
2992 /* since two compares are needed for boundary conditions */
2993 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2996 if (tree->values.switchVals.swDefault)
2997 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2999 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3001 falseLabel = newiTempLabel (buffer);
3003 /* so we can create a jumptable */
3004 /* first we rule out the boundary conditions */
3005 /* if only optimization says so */
3006 if (!optimize.noJTabBoundary)
3008 sym_link *cetype = getSpec (operandType (cond));
3009 /* no need to check the lower bound if
3010 the condition is unsigned & minimum value is zero */
3011 if (!(min == 0 && SPEC_USIGN (cetype)))
3013 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3014 ic = newiCodeCondition (boundary, falseLabel, NULL);
3018 /* now for upper bounds */
3019 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3020 ic = newiCodeCondition (boundary, falseLabel, NULL);
3024 /* if the min is not zero then we no make it zero */
3027 cond = geniCodeSubtract (cond, operandFromLit (min));
3028 setOperandType (cond, UCHARTYPE);
3031 /* now create the jumptable */
3032 ic = newiCode (JUMPTABLE, NULL, NULL);
3033 IC_JTCOND (ic) = cond;
3034 IC_JTLABELS (ic) = labels;
3039 /*-----------------------------------------------------------------*/
3040 /* geniCodeSwitch - changes a switch to a if statement */
3041 /*-----------------------------------------------------------------*/
3043 geniCodeSwitch (ast * tree)
3046 operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
3047 value *caseVals = tree->values.switchVals.swVals;
3048 symbol *trueLabel, *falseLabel;
3050 /* if we can make this a jump table */
3051 if (geniCodeJumpTable (cond, caseVals, tree))
3052 goto jumpTable; /* no need for the comparison */
3054 /* for the cases defined do */
3058 operand *compare = geniCodeLogic (cond,
3059 operandFromValue (caseVals),
3062 sprintf (buffer, "_case_%d_%d",
3063 tree->values.switchVals.swNum,
3064 (int) floatFromVal (caseVals));
3065 trueLabel = newiTempLabel (buffer);
3067 ic = newiCodeCondition (compare, trueLabel, NULL);
3069 caseVals = caseVals->next;
3074 /* if default is present then goto break else break */
3075 if (tree->values.switchVals.swDefault)
3076 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3078 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3080 falseLabel = newiTempLabel (buffer);
3081 geniCodeGoto (falseLabel);
3084 ast2iCode (tree->right);
3087 /*-----------------------------------------------------------------*/
3088 /* geniCodeInline - intermediate code for inline assembler */
3089 /*-----------------------------------------------------------------*/
3091 geniCodeInline (ast * tree)
3095 ic = newiCode (INLINEASM, NULL, NULL);
3096 IC_INLINE (ic) = tree->values.inlineasm;
3100 /*-----------------------------------------------------------------*/
3101 /* ast2iCode - creates an icodeList from an ast */
3102 /*-----------------------------------------------------------------*/
3104 ast2iCode (ast * tree)
3106 operand *left = NULL;
3107 operand *right = NULL;
3112 /* set the global variables for filename & line number */
3114 filename = tree->filename;
3116 lineno = tree->lineno;
3118 block = tree->block;
3120 scopeLevel = tree->level;
3122 if (tree->type == EX_VALUE)
3123 return operandFromValue (tree->opval.val);
3125 if (tree->type == EX_LINK)
3126 return operandFromLink (tree->opval.lnk);
3128 /* if we find a nullop */
3129 if (tree->type == EX_OP &&
3130 (tree->opval.op == NULLOP ||
3131 tree->opval.op == BLOCK))
3133 ast2iCode (tree->left);
3134 ast2iCode (tree->right);
3138 /* special cases for not evaluating */
3139 if (tree->opval.op != ':' &&
3140 tree->opval.op != '?' &&
3141 tree->opval.op != CALL &&
3142 tree->opval.op != IFX &&
3143 tree->opval.op != LABEL &&
3144 tree->opval.op != GOTO &&
3145 tree->opval.op != SWITCH &&
3146 tree->opval.op != FUNCTION &&
3147 tree->opval.op != INLINEASM)
3150 if (IS_ASSIGN_OP (tree->opval.op) ||
3151 IS_DEREF_OP (tree) ||
3152 (tree->opval.op == '&' && !tree->right) ||
3153 tree->opval.op == PTR_OP)
3156 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3157 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3159 int olvr = lvaluereq;
3161 left = operandFromAst (tree->left);
3162 lvaluereq = olvr - 1;
3166 left = operandFromAst (tree->left);
3169 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3170 left = geniCodeRValue (left, TRUE);
3174 left = operandFromAst (tree->left);
3176 if (tree->opval.op == INC_OP ||
3177 tree->opval.op == DEC_OP)
3180 right = operandFromAst (tree->right);
3185 right = operandFromAst (tree->right);
3189 /* now depending on the type of operand */
3190 /* this will be a biggy */
3191 switch (tree->opval.op)
3194 case '[': /* array operation */
3196 sym_link *ltype = operandType (left);
3197 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3198 right = geniCodeRValue (right, TRUE);
3201 return geniCodeArray (left, right);
3203 case '.': /* structure dereference */
3204 if (IS_PTR (operandType (left)))
3205 left = geniCodeRValue (left, TRUE);
3207 left = geniCodeRValue (left, FALSE);
3209 return geniCodeStruct (left, right, tree->lvalue);
3211 case PTR_OP: /* structure pointer dereference */
3214 pType = operandType (left);
3215 left = geniCodeRValue (left, TRUE);
3217 setOClass (pType, getSpec (operandType (left)));
3220 return geniCodeStruct (left, right, tree->lvalue);
3222 case INC_OP: /* increment operator */
3224 return geniCodePostInc (left);
3226 return geniCodePreInc (right);
3228 case DEC_OP: /* decrement operator */
3230 return geniCodePostDec (left);
3232 return geniCodePreDec (right);
3234 case '&': /* bitwise and or address of operator */
3236 { /* this is a bitwise operator */
3237 left = geniCodeRValue (left, FALSE);
3238 right = geniCodeRValue (right, FALSE);
3239 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3242 return geniCodeAddressOf (left);
3244 case '|': /* bitwise or & xor */
3246 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3247 geniCodeRValue (right, FALSE),
3252 return geniCodeDivision (geniCodeRValue (left, FALSE),
3253 geniCodeRValue (right, FALSE));
3256 return geniCodeModulus (geniCodeRValue (left, FALSE),
3257 geniCodeRValue (right, FALSE));
3260 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3261 geniCodeRValue (right, FALSE), FALSE,IS_INT(tree->ftype));
3263 return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
3267 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3268 geniCodeRValue (right, FALSE));
3270 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3274 return geniCodeAdd (geniCodeRValue (left, FALSE),
3275 geniCodeRValue (right, FALSE));
3277 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3280 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3281 geniCodeRValue (right, FALSE));
3284 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3285 geniCodeRValue (right, FALSE));
3287 return geniCodeCast (operandType (left),
3288 geniCodeRValue (right, FALSE), FALSE);
3294 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3298 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3299 setOperandType (op, UCHARTYPE);
3310 return geniCodeLogic (geniCodeRValue (left, FALSE),
3311 geniCodeRValue (right, FALSE),
3314 return geniCodeConditional (tree);
3317 return operandFromLit (getSize (tree->right->ftype));
3321 sym_link *rtype = operandType (right);
3322 sym_link *ltype = operandType (left);
3323 if (IS_PTR (rtype) && IS_ITEMP (right)
3324 && right->isaddr && checkType (rtype->next, ltype) == 1)
3325 right = geniCodeRValue (right, TRUE);
3327 right = geniCodeRValue (right, FALSE);
3329 geniCodeAssign (left, right, 0);
3334 geniCodeAssign (left,
3335 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3337 geniCodeRValue (right, FALSE), FALSE,FALSE), 0);
3341 geniCodeAssign (left,
3342 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3344 geniCodeRValue (right, FALSE)), 0);
3347 geniCodeAssign (left,
3348 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3350 geniCodeRValue (right, FALSE)), 0);
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)
3357 right = geniCodeRValue (right, TRUE);
3359 right = geniCodeRValue (right, FALSE);
3362 return geniCodeAssign (left,
3363 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3369 sym_link *rtype = operandType (right);
3370 sym_link *ltype = operandType (left);
3371 if (IS_PTR (rtype) && IS_ITEMP (right)
3372 && right->isaddr && checkType (rtype->next, ltype) == 1)
3374 right = geniCodeRValue (right, TRUE);
3378 right = geniCodeRValue (right, FALSE);
3381 geniCodeAssign (left,
3382 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3388 geniCodeAssign (left,
3389 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3391 geniCodeRValue (right, FALSE)), 0);
3394 geniCodeAssign (left,
3395 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3397 geniCodeRValue (right, FALSE)), 0);
3400 geniCodeAssign (left,
3401 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3403 geniCodeRValue (right, FALSE),
3405 operandType (left)), 0);
3408 geniCodeAssign (left,
3409 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3411 geniCodeRValue (right, FALSE),
3413 operandType (left)), 0);
3416 geniCodeAssign (left,
3417 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3419 geniCodeRValue (right, FALSE),
3421 operandType (left)), 0);
3423 return geniCodeRValue (right, FALSE);
3426 return geniCodeCall (ast2iCode (tree->left),
3429 geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
3430 return ast2iCode (tree->right);
3433 geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
3434 return ast2iCode (tree->right);
3437 geniCodeFunctionBody (tree);
3441 geniCodeReturn (right);
3449 geniCodeSwitch (tree);
3453 geniCodeInline (tree);
3460 /*-----------------------------------------------------------------*/
3461 /* reverseICChain - gets from the list and creates a linkedlist */
3462 /*-----------------------------------------------------------------*/
3469 while ((loop = getSet (&iCodeChain)))
3481 /*-----------------------------------------------------------------*/
3482 /* iCodeFromAst - given an ast will convert it to iCode */
3483 /*-----------------------------------------------------------------*/
3485 iCodeFromAst (ast * tree)
3487 returnLabel = newiTempLabel ("_return");
3488 entryLabel = newiTempLabel ("_entry");
3490 return reverseiCChain ();