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 ic 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)) && (!TARGET_IS_DS390)) &&
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)) || TARGET_IS_DS390))
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);
1682 SPEC_NOUN(getSpec(resType))=V_INT;
1683 SPEC_SHORT(getSpec(resType))=0;
1687 /* if the right is a literal & power of 2 */
1688 /* then make it a left shift */
1689 /*If we are computing ptr size then normal multiplication */
1690 /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
1691 /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
1692 if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
1693 !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
1694 (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
1696 if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)))
1698 /* LEFT_OP need same size for left and result, */
1699 left = geniCodeCast (resType, left, TRUE);
1700 ltype = operandType (left);
1702 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1706 ic = newiCode ('*', left, right); /* normal multiplication */
1707 /* if the size left or right > 1 then support routine */
1708 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1712 IC_RESULT (ic) = newiTempOperand (resType, 1);
1715 return IC_RESULT (ic);
1718 /*-----------------------------------------------------------------*/
1719 /* geniCodeDivision - gen intermediate code for division */
1720 /*-----------------------------------------------------------------*/
1722 geniCodeDivision (operand * left, operand * right)
1727 sym_link *rtype = operandType (right);
1728 sym_link *retype = getSpec (rtype);
1729 sym_link *ltype = operandType (left);
1730 sym_link *letype = getSpec (ltype);
1732 resType = usualBinaryConversions (&left, &right);
1734 /* if the right is a literal & power of 2 */
1735 /* then make it a right shift */
1736 if (IS_LITERAL (retype) &&
1737 !IS_FLOAT (letype) &&
1738 (p2 = powof2 ((unsigned long)
1739 floatFromVal (right->operand.valOperand))))
1740 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1743 ic = newiCode ('/', left, right); /* normal division */
1744 /* if the size left or right > 1 then support routine */
1745 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1748 IC_RESULT (ic) = newiTempOperand (resType, 0);
1751 return IC_RESULT (ic);
1753 /*-----------------------------------------------------------------*/
1754 /* geniCodeModulus - gen intermediate code for modulus */
1755 /*-----------------------------------------------------------------*/
1757 geniCodeModulus (operand * left, operand * right)
1763 /* if they are both literal then we know the result */
1764 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1765 return operandFromValue (valMod (left->operand.valOperand,
1766 right->operand.valOperand));
1768 resType = usualBinaryConversions (&left, &right);
1770 /* now they are the same size */
1771 ic = newiCode ('%', left, right);
1773 /* if the size left or right > 1 then support routine */
1774 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1776 IC_RESULT (ic) = newiTempOperand (resType, 0);
1779 return IC_RESULT (ic);
1782 /*-----------------------------------------------------------------*/
1783 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1784 /*-----------------------------------------------------------------*/
1786 geniCodePtrPtrSubtract (operand * left, operand * right)
1792 /* if they are both literals then */
1793 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1795 result = operandFromValue (valMinus (left->operand.valOperand,
1796 right->operand.valOperand));
1800 ic = newiCode ('-', left, right);
1802 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1806 return geniCodeDivision (result,
1807 operandFromLit (getSize (ltype->next)));
1810 /*-----------------------------------------------------------------*/
1811 /* geniCodeSubtract - generates code for subtraction */
1812 /*-----------------------------------------------------------------*/
1814 geniCodeSubtract (operand * left, operand * right)
1821 /* if they both pointers then */
1822 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1823 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1824 return geniCodePtrPtrSubtract (left, right);
1826 /* if they are both literal then we know the result */
1827 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1828 && left->isLiteral && right->isLiteral)
1829 return operandFromValue (valMinus (left->operand.valOperand,
1830 right->operand.valOperand));
1832 /* if left is an array or pointer */
1833 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1835 isarray = left->isaddr;
1836 right = geniCodeMultiply (right,
1837 operandFromLit (getSize (ltype->next)), TRUE, FALSE);
1838 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1841 { /* make them the same size */
1842 resType = usualBinaryConversions (&left, &right);
1845 ic = newiCode ('-', left, right);
1847 IC_RESULT (ic) = newiTempOperand (resType, 1);
1848 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1850 /* if left or right is a float */
1851 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1855 return IC_RESULT (ic);
1858 /*-----------------------------------------------------------------*/
1859 /* geniCodeAdd - generates iCode for addition */
1860 /*-----------------------------------------------------------------*/
1862 geniCodeAdd (operand * left, operand * right)
1870 /* if left is an array then array access */
1871 if (IS_ARRAY (ltype))
1872 return geniCodeArray (left, right);
1874 /* if the right side is LITERAL zero */
1875 /* return the left side */
1876 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1879 /* if left is literal zero return right */
1880 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1883 /* if left is an array or pointer then size */
1887 isarray = left->isaddr;
1889 operandFromLit (getSize (ltype->next));
1891 right = geniCodeMultiply (right, size, (getSize (ltype) != 1),FALSE);
1893 resType = copyLinkChain (ltype);
1896 { /* make them the same size */
1897 resType = usualBinaryConversions (&left, &right);
1900 /* if they are both literals then we know */
1901 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1902 && left->isLiteral && right->isLiteral)
1903 return operandFromValue (valPlus (valFromType (letype),
1904 valFromType (retype)));
1906 ic = newiCode ('+', left, right);
1908 IC_RESULT (ic) = newiTempOperand (resType, 1);
1909 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1911 /* if left or right is a float then support
1913 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1918 return IC_RESULT (ic);
1922 /*-----------------------------------------------------------------*/
1923 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1924 /*-----------------------------------------------------------------*/
1926 aggrToPtr (sym_link * type, bool force)
1932 if (IS_PTR (type) && !force)
1935 etype = getSpec (type);
1939 /* if the output class is generic */
1940 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1941 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1943 /* if the variable was declared a constant */
1944 /* then the pointer points to a constant */
1945 if (IS_CONSTANT (etype))
1946 DCL_PTR_CONST (ptype) = 1;
1948 /* the variable was volatile then pointer to volatile */
1949 if (IS_VOLATILE (etype))
1950 DCL_PTR_VOLATILE (ptype) = 1;
1954 /*-----------------------------------------------------------------*/
1955 /* geniCodeArray2Ptr - array to pointer */
1956 /*-----------------------------------------------------------------*/
1958 geniCodeArray2Ptr (operand * op)
1960 sym_link *optype = operandType (op);
1961 sym_link *opetype = getSpec (optype);
1963 /* set the pointer depending on the storage class */
1964 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1965 DCL_PTR_CONST (optype) = port->mem.code_ro;
1968 /* if the variable was declared a constant */
1969 /* then the pointer points to a constant */
1970 if (IS_CONSTANT (opetype))
1971 DCL_PTR_CONST (optype) = 1;
1973 /* the variable was volatile then pointer to volatile */
1974 if (IS_VOLATILE (opetype))
1975 DCL_PTR_VOLATILE (optype) = 1;
1981 /*-----------------------------------------------------------------*/
1982 /* geniCodeArray - array access */
1983 /*-----------------------------------------------------------------*/
1985 geniCodeArray (operand * left, operand * right)
1988 sym_link *ltype = operandType (left);
1992 if (IS_PTR (ltype->next) && left->isaddr)
1994 left = geniCodeRValue (left, FALSE);
1996 return geniCodeDerefPtr (geniCodeAdd (left, right));
2000 right = geniCodeMultiply (right,
2001 operandFromLit (getSize (ltype->next)), TRUE,FALSE);
2003 /* we can check for limits here */
2004 if (isOperandLiteral (right) &&
2007 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2009 werror (E_ARRAY_BOUND);
2010 right = operandFromLit (0);
2013 ic = newiCode ('+', left, right);
2015 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2016 !IS_AGGREGATE (ltype->next) &&
2017 !IS_PTR (ltype->next))
2018 ? ltype : ltype->next), 0);
2020 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2022 return IC_RESULT (ic);
2025 /*-----------------------------------------------------------------*/
2026 /* geniCodeStruct - generates intermediate code for structres */
2027 /*-----------------------------------------------------------------*/
2029 geniCodeStruct (operand * left, operand * right, bool islval)
2032 sym_link *type = operandType (left);
2033 sym_link *etype = getSpec (type);
2035 symbol *element = getStructElement (SPEC_STRUCT (etype),
2036 right->operand.symOperand);
2038 /* add the offset */
2039 ic = newiCode ('+', left, operandFromLit (element->offset));
2041 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2043 /* preserve the storage & output class of the struct */
2044 /* as well as the volatile attribute */
2045 retype = getSpec (operandType (IC_RESULT (ic)));
2046 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2047 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2048 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2050 if (IS_PTR (element->type))
2051 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2053 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2057 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2060 /*-----------------------------------------------------------------*/
2061 /* geniCodePostInc - generate int code for Post increment */
2062 /*-----------------------------------------------------------------*/
2064 geniCodePostInc (operand * op)
2068 sym_link *optype = operandType (op);
2070 operand *rv = (IS_ITEMP (op) ?
2071 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2073 sym_link *rvtype = operandType (rv);
2076 /* if this is not an address we have trouble */
2079 werror (E_LVALUE_REQUIRED, "++");
2083 rOp = newiTempOperand (rvtype, 0);
2089 geniCodeAssign (rOp, rv, 0);
2091 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2092 if (IS_FLOAT (rvtype))
2093 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2095 ic = newiCode ('+', rv, operandFromLit (size));
2097 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2100 geniCodeAssign (op, result, 0);
2106 /*-----------------------------------------------------------------*/
2107 /* geniCodePreInc - generate code for preIncrement */
2108 /*-----------------------------------------------------------------*/
2110 geniCodePreInc (operand * op)
2113 sym_link *optype = operandType (op);
2114 operand *rop = (IS_ITEMP (op) ?
2115 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2117 sym_link *roptype = operandType (rop);
2123 werror (E_LVALUE_REQUIRED, "++");
2128 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2129 if (IS_FLOAT (roptype))
2130 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2132 ic = newiCode ('+', rop, operandFromLit (size));
2133 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2137 return geniCodeAssign (op, result, 0);
2140 /*-----------------------------------------------------------------*/
2141 /* geniCodePostDec - generates code for Post decrement */
2142 /*-----------------------------------------------------------------*/
2144 geniCodePostDec (operand * op)
2148 sym_link *optype = operandType (op);
2150 operand *rv = (IS_ITEMP (op) ?
2151 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2153 sym_link *rvtype = operandType (rv);
2156 /* if this is not an address we have trouble */
2159 werror (E_LVALUE_REQUIRED, "++");
2163 rOp = newiTempOperand (rvtype, 0);
2169 geniCodeAssign (rOp, rv, 0);
2171 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2172 if (IS_FLOAT (rvtype))
2173 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2175 ic = newiCode ('-', rv, operandFromLit (size));
2177 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2180 geniCodeAssign (op, result, 0);
2186 /*-----------------------------------------------------------------*/
2187 /* geniCodePreDec - generate code for pre decrement */
2188 /*-----------------------------------------------------------------*/
2190 geniCodePreDec (operand * op)
2193 sym_link *optype = operandType (op);
2194 operand *rop = (IS_ITEMP (op) ?
2195 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2197 sym_link *roptype = operandType (rop);
2203 werror (E_LVALUE_REQUIRED, "++");
2208 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2209 if (IS_FLOAT (roptype))
2210 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2212 ic = newiCode ('-', rop, operandFromLit (size));
2213 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2217 return geniCodeAssign (op, result, 0);
2221 /*-----------------------------------------------------------------*/
2222 /* geniCodeBitwise - gen int code for bitWise operators */
2223 /*-----------------------------------------------------------------*/
2225 geniCodeBitwise (operand * left, operand * right,
2226 int oper, sym_link * resType)
2230 left = geniCodeCast (resType, left, TRUE);
2231 right = geniCodeCast (resType, right, TRUE);
2233 ic = newiCode (oper, left, right);
2234 IC_RESULT (ic) = newiTempOperand (resType, 0);
2237 return IC_RESULT (ic);
2240 /*-----------------------------------------------------------------*/
2241 /* geniCodeAddressOf - gens icode for '&' address of operator */
2242 /*-----------------------------------------------------------------*/
2244 geniCodeAddressOf (operand * op)
2248 sym_link *optype = operandType (op);
2249 sym_link *opetype = getSpec (optype);
2251 /* lvalue check already done in decorateType */
2252 /* this must be a lvalue */
2253 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2254 /* werror (E_LVALUE_REQUIRED,"&"); */
2259 p->class = DECLARATOR;
2261 /* set the pointer depending on the storage class */
2262 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2263 DCL_PTR_CONST (p) = port->mem.code_ro;
2265 /* make sure we preserve the const & volatile */
2266 if (IS_CONSTANT (opetype))
2267 DCL_PTR_CONST (p) = 1;
2269 if (IS_VOLATILE (opetype))
2270 DCL_PTR_VOLATILE (p) = 1;
2272 p->next = copyLinkChain (optype);
2274 /* if already a temp */
2277 setOperandType (op, p);
2282 /* other wise make this of the type coming in */
2283 ic = newiCode (ADDRESS_OF, op, NULL);
2284 IC_RESULT (ic) = newiTempOperand (p, 1);
2285 IC_RESULT (ic)->isaddr = 0;
2287 return IC_RESULT (ic);
2289 /*-----------------------------------------------------------------*/
2290 /* setOClass - sets the output class depending on the pointer type */
2291 /*-----------------------------------------------------------------*/
2293 setOClass (sym_link * ptr, sym_link * spec)
2295 switch (DCL_TYPE (ptr))
2298 SPEC_OCLS (spec) = data;
2302 SPEC_OCLS (spec) = generic;
2306 SPEC_OCLS (spec) = xdata;
2310 SPEC_OCLS (spec) = code;
2314 SPEC_OCLS (spec) = idata;
2318 SPEC_OCLS (spec) = xstack;
2322 SPEC_OCLS (spec) = eeprom;
2331 /*-----------------------------------------------------------------*/
2332 /* geniCodeDerefPtr - dereference pointer with '*' */
2333 /*-----------------------------------------------------------------*/
2335 geniCodeDerefPtr (operand * op)
2337 sym_link *rtype, *retype;
2338 sym_link *optype = operandType (op);
2340 /* if this is a pointer then generate the rvalue */
2341 if (IS_PTR (optype))
2343 if (IS_TRUE_SYMOP (op))
2346 op = geniCodeRValue (op, TRUE);
2349 op = geniCodeRValue (op, TRUE);
2352 /* now get rid of the pointer part */
2353 if (lvaluereq && IS_ITEMP (op))
2355 retype = getSpec (rtype = copyLinkChain (optype));
2359 retype = getSpec (rtype = copyLinkChain (optype->next));
2362 /* if this is a pointer then outputclass needs 2b updated */
2363 if (IS_PTR (optype))
2364 setOClass (optype, retype);
2366 op->isGptr = IS_GENPTR (optype);
2368 /* if the pointer was declared as a constant */
2369 /* then we cannot allow assignment to the derefed */
2370 if (IS_PTR_CONST (optype))
2371 SPEC_CONST (retype) = 1;
2373 op->isaddr = (IS_PTR (rtype) ||
2374 IS_STRUCT (rtype) ||
2380 op = geniCodeRValue (op, TRUE);
2382 setOperandType (op, rtype);
2387 /*-----------------------------------------------------------------*/
2388 /* geniCodeUnaryMinus - does a unary minus of the operand */
2389 /*-----------------------------------------------------------------*/
2391 geniCodeUnaryMinus (operand * op)
2394 sym_link *optype = operandType (op);
2396 if (IS_LITERAL (optype))
2397 return operandFromLit (-floatFromVal (op->operand.valOperand));
2399 ic = newiCode (UNARYMINUS, op, NULL);
2400 IC_RESULT (ic) = newiTempOperand (optype, 0);
2402 return IC_RESULT (ic);
2405 /*-----------------------------------------------------------------*/
2406 /* geniCodeLeftShift - gen i code for left shift */
2407 /*-----------------------------------------------------------------*/
2409 geniCodeLeftShift (operand * left, operand * right)
2414 /* Note that we don't use the usual binary conversions for the
2415 * shift operations, in accordance with our ANSI friends.
2417 if (options.ANSIint)
2419 right = usualUnaryConversions (right);
2420 left = usualUnaryConversions (left);
2423 ic = newiCode (LEFT_OP, left, right);
2424 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2426 return IC_RESULT (ic);
2429 /*-----------------------------------------------------------------*/
2430 /* geniCodeRightShift - gen i code for right shift */
2431 /*-----------------------------------------------------------------*/
2433 geniCodeRightShift (operand * left, operand * right)
2438 /* Note that we don't use the usual binary conversions for the
2439 * shift operations, in accordance with our ANSI friends.
2441 if (options.ANSIint)
2443 right = usualUnaryConversions (right);
2444 left = usualUnaryConversions (left);
2447 ic = newiCode (RIGHT_OP, left, right);
2448 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2450 return IC_RESULT (ic);
2453 #if defined(__BORLANDC__) || defined(_MSC_VER)
2454 #define LONG_LONG __int64
2456 #define LONG_LONG long long
2459 /*-----------------------------------------------------------------*/
2460 /* geniCodeLogic- logic code */
2461 /*-----------------------------------------------------------------*/
2463 geniCodeLogic (operand * left, operand * right, int op)
2467 sym_link *rtype = operandType (right);
2468 sym_link *ltype = operandType (left);
2470 /* left is integral type and right is literal then
2471 check if the literal value is within bounds */
2472 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2474 int nbits = bitsForType (ltype);
2475 long v = operandLitValue (right);
2477 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2478 werror (W_CONST_RANGE, " compare operation ");
2481 ctype = usualBinaryConversions (&left, &right);
2483 ic = newiCode (op, left, right);
2484 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2486 /* if comparing anything greater than one byte
2487 and not a '==' || '!=' || '&&' || '||' (these
2489 if (getSize (ctype) > 1 &&
2497 return IC_RESULT (ic);
2500 /*-----------------------------------------------------------------*/
2501 /* geniCodeUnary - for a a generic unary operation */
2502 /*-----------------------------------------------------------------*/
2504 geniCodeUnary (operand * op, int oper)
2506 iCode *ic = newiCode (oper, op, NULL);
2508 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2510 return IC_RESULT (ic);
2513 /*-----------------------------------------------------------------*/
2514 /* geniCodeConditional - geniCode for '?' ':' operation */
2515 /*-----------------------------------------------------------------*/
2517 geniCodeConditional (ast * tree)
2520 symbol *falseLabel = newiTempLabel (NULL);
2521 symbol *exitLabel = newiTempLabel (NULL);
2522 operand *cond = ast2iCode (tree->left);
2523 operand *true, *false, *result;
2525 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2529 true = ast2iCode (tree->right->left);
2531 /* move the value to a new Operand */
2532 result = newiTempOperand (operandType (true), 0);
2533 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2535 /* generate an unconditional goto */
2536 geniCodeGoto (exitLabel);
2538 /* now for the right side */
2539 geniCodeLabel (falseLabel);
2541 false = ast2iCode (tree->right->right);
2542 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2544 /* create the exit label */
2545 geniCodeLabel (exitLabel);
2550 /*-----------------------------------------------------------------*/
2551 /* geniCodeAssign - generate code for assignment */
2552 /*-----------------------------------------------------------------*/
2554 geniCodeAssign (operand * left, operand * right, int nosupdate)
2557 sym_link *ltype = operandType (left);
2558 sym_link *rtype = operandType (right);
2560 if (!left->isaddr && !IS_ITEMP (left))
2562 werror (E_LVALUE_REQUIRED, "assignment");
2566 /* left is integral type and right is literal then
2567 check if the literal value is within bounds */
2568 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2570 int nbits = bitsForType (ltype);
2571 long v = operandLitValue (right);
2573 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2574 werror (W_CONST_RANGE, " = operation");
2577 /* if the left & right type don't exactly match */
2578 /* if pointer set then make sure the check is
2579 done with the type & not the pointer */
2580 /* then cast rights type to left */
2582 /* first check the type for pointer assignement */
2583 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2584 checkType (ltype, rtype) < 0)
2586 if (checkType (ltype->next, rtype) < 0)
2587 right = geniCodeCast (ltype->next, right, TRUE);
2589 else if (checkType (ltype, rtype) < 0)
2590 right = geniCodeCast (ltype, right, TRUE);
2592 /* if left is a true symbol & ! volatile
2593 create an assignment to temporary for
2594 the right & then assign this temporary
2595 to the symbol this is SSA . isn't it simple
2596 and folks have published mountains of paper on it */
2597 if (IS_TRUE_SYMOP (left) &&
2598 !isOperandVolatile (left, FALSE) &&
2599 isOperandGlobal (left))
2603 if (IS_TRUE_SYMOP (right))
2604 sym = OP_SYMBOL (right);
2605 ic = newiCode ('=', NULL, right);
2606 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2607 SPIL_LOC (right) = sym;
2611 ic = newiCode ('=', NULL, right);
2612 IC_RESULT (ic) = left;
2615 /* if left isgptr flag is set then support
2616 routine will be required */
2620 ic->nosupdate = nosupdate;
2624 /*-----------------------------------------------------------------*/
2625 /* geniCodeSEParms - generate code for side effecting fcalls */
2626 /*-----------------------------------------------------------------*/
2628 geniCodeSEParms (ast * parms)
2633 if (parms->type == EX_OP && parms->opval.op == PARAM)
2635 geniCodeSEParms (parms->left);
2636 geniCodeSEParms (parms->right);
2640 /* hack don't like this but too lazy to think of
2642 if (IS_ADDRESS_OF_OP (parms))
2643 parms->left->lvalue = 1;
2645 if (IS_CAST_OP (parms) &&
2646 IS_PTR (parms->ftype) &&
2647 IS_ADDRESS_OF_OP (parms->right))
2648 parms->right->left->lvalue = 1;
2650 parms->opval.oprnd =
2651 geniCodeRValue (ast2iCode (parms), FALSE);
2653 parms->type = EX_OPERAND;
2656 /*-----------------------------------------------------------------*/
2657 /* geniCodeParms - generates parameters */
2658 /*-----------------------------------------------------------------*/
2660 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
2668 /* if this is a param node then do the left & right */
2669 if (parms->type == EX_OP && parms->opval.op == PARAM)
2671 geniCodeParms (parms->left, stack, fetype, func);
2672 geniCodeParms (parms->right, stack, fetype, func);
2676 /* get the parameter value */
2677 if (parms->type == EX_OPERAND)
2678 pval = parms->opval.oprnd;
2681 /* maybe this else should go away ?? */
2682 /* hack don't like this but too lazy to think of
2684 if (IS_ADDRESS_OF_OP (parms))
2685 parms->left->lvalue = 1;
2687 if (IS_CAST_OP (parms) &&
2688 IS_PTR (parms->ftype) &&
2689 IS_ADDRESS_OF_OP (parms->right))
2690 parms->right->left->lvalue = 1;
2692 pval = geniCodeRValue (ast2iCode (parms), FALSE);
2695 /* if register parm then make it a send */
2696 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2697 IS_REGPARM (parms->etype)) && !func->hasVargs)
2699 ic = newiCode (SEND, pval, NULL);
2704 /* now decide whether to push or assign */
2705 if (!(options.stackAuto || IS_RENT (fetype)))
2709 operand *top = operandFromSymbol (parms->argSym);
2710 geniCodeAssign (top, pval, 1);
2714 sym_link *p = operandType (pval);
2716 ic = newiCode (IPUSH, pval, NULL);
2718 /* update the stack adjustment */
2719 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2726 /*-----------------------------------------------------------------*/
2727 /* geniCodeCall - generates temp code for calling */
2728 /*-----------------------------------------------------------------*/
2730 geniCodeCall (operand * left, ast * parms)
2734 sym_link *type, *etype;
2737 /* take care of parameters with side-effecting
2738 function calls in them, this is required to take care
2739 of overlaying function parameters */
2740 geniCodeSEParms (parms);
2742 /* first the parameters */
2743 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
2745 /* now call : if symbol then pcall */
2746 if (IS_OP_POINTER (left))
2747 ic = newiCode (PCALL, left, NULL);
2749 ic = newiCode (CALL, left, NULL);
2751 IC_ARGS (ic) = left->operand.symOperand->args;
2752 type = copyLinkChain (operandType (left)->next);
2753 etype = getSpec (type);
2754 SPEC_EXTR (etype) = 0;
2755 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2759 /* stack adjustment after call */
2760 ic->parmBytes = stack;
2765 /*-----------------------------------------------------------------*/
2766 /* geniCodeReceive - generate intermediate code for "receive" */
2767 /*-----------------------------------------------------------------*/
2769 geniCodeReceive (value * args)
2771 /* for all arguments that are passed in registers */
2775 if (IS_REGPARM (args->etype))
2777 operand *opr = operandFromValue (args);
2779 symbol *sym = OP_SYMBOL (opr);
2782 /* we will use it after all optimizations
2783 and before liveRange calculation */
2784 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2787 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2788 options.stackAuto == 0 &&
2794 opl = newiTempOperand (args->type, 0);
2796 sym->reqv->key = sym->key;
2797 OP_SYMBOL (sym->reqv)->key = sym->key;
2798 OP_SYMBOL (sym->reqv)->isreqv = 1;
2799 OP_SYMBOL (sym->reqv)->islocal = 0;
2800 SPIL_LOC (sym->reqv) = sym;
2804 ic = newiCode (RECEIVE, NULL, NULL);
2805 currFunc->recvSize = getSize (sym->etype);
2806 IC_RESULT (ic) = opr;
2814 /*-----------------------------------------------------------------*/
2815 /* geniCodeFunctionBody - create the function body */
2816 /*-----------------------------------------------------------------*/
2818 geniCodeFunctionBody (ast * tree)
2825 /* reset the auto generation */
2831 func = ast2iCode (tree->left);
2832 fetype = getSpec (operandType (func));
2834 savelineno = lineno;
2835 lineno = OP_SYMBOL (func)->lineDef;
2836 /* create an entry label */
2837 geniCodeLabel (entryLabel);
2838 lineno = savelineno;
2840 /* create a proc icode */
2841 ic = newiCode (FUNCTION, func, NULL);
2842 /* if the function has parmas then */
2843 /* save the parameters information */
2844 ic->argLabel.args = tree->values.args;
2845 ic->lineno = OP_SYMBOL (func)->lineDef;
2849 /* for all parameters that are passed
2850 on registers add a "receive" */
2851 geniCodeReceive (tree->values.args);
2853 /* generate code for the body */
2854 ast2iCode (tree->right);
2856 /* create a label for return */
2857 geniCodeLabel (returnLabel);
2859 /* now generate the end proc */
2860 ic = newiCode (ENDFUNCTION, func, NULL);
2865 /*-----------------------------------------------------------------*/
2866 /* geniCodeReturn - gen icode for 'return' statement */
2867 /*-----------------------------------------------------------------*/
2869 geniCodeReturn (operand * op)
2873 /* if the operand is present force an rvalue */
2875 op = geniCodeRValue (op, FALSE);
2877 ic = newiCode (RETURN, op, NULL);
2881 /*-----------------------------------------------------------------*/
2882 /* geniCodeIfx - generates code for extended if statement */
2883 /*-----------------------------------------------------------------*/
2885 geniCodeIfx (ast * tree)
2888 operand *condition = ast2iCode (tree->left);
2891 /* if condition is null then exit */
2895 condition = geniCodeRValue (condition, FALSE);
2897 cetype = getSpec (operandType (condition));
2898 /* if the condition is a literal */
2899 if (IS_LITERAL (cetype))
2901 if (floatFromVal (condition->operand.valOperand))
2903 if (tree->trueLabel)
2904 geniCodeGoto (tree->trueLabel);
2910 if (tree->falseLabel)
2911 geniCodeGoto (tree->falseLabel);
2918 if (tree->trueLabel)
2920 ic = newiCodeCondition (condition,
2925 if (tree->falseLabel)
2926 geniCodeGoto (tree->falseLabel);
2930 ic = newiCodeCondition (condition,
2937 ast2iCode (tree->right);
2940 /*-----------------------------------------------------------------*/
2941 /* geniCodeJumpTable - tries to create a jump table for switch */
2942 /*-----------------------------------------------------------------*/
2944 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2946 int min = 0, max = 0, t, cnt = 0;
2953 if (!tree || !caseVals)
2956 /* the criteria for creating a jump table is */
2957 /* all integer numbers between the maximum & minimum must */
2958 /* be present , the maximum value should not exceed 255 */
2959 min = max = (int) floatFromVal (vch = caseVals);
2960 sprintf (buffer, "_case_%d_%d",
2961 tree->values.switchVals.swNum,
2963 addSet (&labels, newiTempLabel (buffer));
2965 /* if there is only one case value then no need */
2966 if (!(vch = vch->next))
2971 if (((t = (int) floatFromVal (vch)) - max) != 1)
2973 sprintf (buffer, "_case_%d_%d",
2974 tree->values.switchVals.swNum,
2976 addSet (&labels, newiTempLabel (buffer));
2982 /* if the number of case statements <= 2 then */
2983 /* it is not economical to create the jump table */
2984 /* since two compares are needed for boundary conditions */
2985 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2988 if (tree->values.switchVals.swDefault)
2989 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2991 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2993 falseLabel = newiTempLabel (buffer);
2995 /* so we can create a jumptable */
2996 /* first we rule out the boundary conditions */
2997 /* if only optimization says so */
2998 if (!optimize.noJTabBoundary)
3000 sym_link *cetype = getSpec (operandType (cond));
3001 /* no need to check the lower bound if
3002 the condition is unsigned & minimum value is zero */
3003 if (!(min == 0 && SPEC_USIGN (cetype)))
3005 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3006 ic = newiCodeCondition (boundary, falseLabel, NULL);
3010 /* now for upper bounds */
3011 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3012 ic = newiCodeCondition (boundary, falseLabel, NULL);
3016 /* if the min is not zero then we no make it zero */
3019 cond = geniCodeSubtract (cond, operandFromLit (min));
3020 setOperandType (cond, UCHARTYPE);
3023 /* now create the jumptable */
3024 ic = newiCode (JUMPTABLE, NULL, NULL);
3025 IC_JTCOND (ic) = cond;
3026 IC_JTLABELS (ic) = labels;
3031 /*-----------------------------------------------------------------*/
3032 /* geniCodeSwitch - changes a switch to a if statement */
3033 /*-----------------------------------------------------------------*/
3035 geniCodeSwitch (ast * tree)
3038 operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
3039 value *caseVals = tree->values.switchVals.swVals;
3040 symbol *trueLabel, *falseLabel;
3042 /* if we can make this a jump table */
3043 if (geniCodeJumpTable (cond, caseVals, tree))
3044 goto jumpTable; /* no need for the comparison */
3046 /* for the cases defined do */
3050 operand *compare = geniCodeLogic (cond,
3051 operandFromValue (caseVals),
3054 sprintf (buffer, "_case_%d_%d",
3055 tree->values.switchVals.swNum,
3056 (int) floatFromVal (caseVals));
3057 trueLabel = newiTempLabel (buffer);
3059 ic = newiCodeCondition (compare, trueLabel, NULL);
3061 caseVals = caseVals->next;
3066 /* if default is present then goto break else break */
3067 if (tree->values.switchVals.swDefault)
3068 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3070 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3072 falseLabel = newiTempLabel (buffer);
3073 geniCodeGoto (falseLabel);
3076 ast2iCode (tree->right);
3079 /*-----------------------------------------------------------------*/
3080 /* geniCodeInline - intermediate code for inline assembler */
3081 /*-----------------------------------------------------------------*/
3083 geniCodeInline (ast * tree)
3087 ic = newiCode (INLINEASM, NULL, NULL);
3088 IC_INLINE (ic) = tree->values.inlineasm;
3092 /*-----------------------------------------------------------------*/
3093 /* ast2iCode - creates an icodeList from an ast */
3094 /*-----------------------------------------------------------------*/
3096 ast2iCode (ast * tree)
3098 operand *left = NULL;
3099 operand *right = NULL;
3104 /* set the global variables for filename & line number */
3106 filename = tree->filename;
3108 lineno = tree->lineno;
3110 block = tree->block;
3112 scopeLevel = tree->level;
3114 if (tree->type == EX_VALUE)
3115 return operandFromValue (tree->opval.val);
3117 if (tree->type == EX_LINK)
3118 return operandFromLink (tree->opval.lnk);
3120 /* if we find a nullop */
3121 if (tree->type == EX_OP &&
3122 (tree->opval.op == NULLOP ||
3123 tree->opval.op == BLOCK))
3125 ast2iCode (tree->left);
3126 ast2iCode (tree->right);
3130 /* special cases for not evaluating */
3131 if (tree->opval.op != ':' &&
3132 tree->opval.op != '?' &&
3133 tree->opval.op != CALL &&
3134 tree->opval.op != IFX &&
3135 tree->opval.op != LABEL &&
3136 tree->opval.op != GOTO &&
3137 tree->opval.op != SWITCH &&
3138 tree->opval.op != FUNCTION &&
3139 tree->opval.op != INLINEASM)
3142 if (IS_ASSIGN_OP (tree->opval.op) ||
3143 IS_DEREF_OP (tree) ||
3144 (tree->opval.op == '&' && !tree->right) ||
3145 tree->opval.op == PTR_OP)
3148 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3149 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3151 int olvr = lvaluereq;
3153 left = operandFromAst (tree->left);
3154 lvaluereq = olvr - 1;
3158 left = operandFromAst (tree->left);
3161 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3162 left = geniCodeRValue (left, TRUE);
3166 left = operandFromAst (tree->left);
3168 if (tree->opval.op == INC_OP ||
3169 tree->opval.op == DEC_OP)
3172 right = operandFromAst (tree->right);
3177 right = operandFromAst (tree->right);
3181 /* now depending on the type of operand */
3182 /* this will be a biggy */
3183 switch (tree->opval.op)
3186 case '[': /* array operation */
3188 sym_link *ltype = operandType (left);
3189 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3190 right = geniCodeRValue (right, TRUE);
3193 return geniCodeArray (left, right);
3195 case '.': /* structure dereference */
3196 if (IS_PTR (operandType (left)))
3197 left = geniCodeRValue (left, TRUE);
3199 left = geniCodeRValue (left, FALSE);
3201 return geniCodeStruct (left, right, tree->lvalue);
3203 case PTR_OP: /* structure pointer dereference */
3206 pType = operandType (left);
3207 left = geniCodeRValue (left, TRUE);
3209 setOClass (pType, getSpec (operandType (left)));
3212 return geniCodeStruct (left, right, tree->lvalue);
3214 case INC_OP: /* increment operator */
3216 return geniCodePostInc (left);
3218 return geniCodePreInc (right);
3220 case DEC_OP: /* decrement operator */
3222 return geniCodePostDec (left);
3224 return geniCodePreDec (right);
3226 case '&': /* bitwise and or address of operator */
3228 { /* this is a bitwise operator */
3229 left = geniCodeRValue (left, FALSE);
3230 right = geniCodeRValue (right, FALSE);
3231 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3234 return geniCodeAddressOf (left);
3236 case '|': /* bitwise or & xor */
3238 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3239 geniCodeRValue (right, FALSE),
3244 return geniCodeDivision (geniCodeRValue (left, FALSE),
3245 geniCodeRValue (right, FALSE));
3248 return geniCodeModulus (geniCodeRValue (left, FALSE),
3249 geniCodeRValue (right, FALSE));
3252 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3253 geniCodeRValue (right, FALSE), FALSE,IS_INT(tree->ftype));
3255 return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
3259 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3260 geniCodeRValue (right, FALSE));
3262 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3266 return geniCodeAdd (geniCodeRValue (left, FALSE),
3267 geniCodeRValue (right, FALSE));
3269 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3272 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3273 geniCodeRValue (right, FALSE));
3276 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3277 geniCodeRValue (right, FALSE));
3279 return geniCodeCast (operandType (left),
3280 geniCodeRValue (right, FALSE), FALSE);
3286 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3290 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3291 setOperandType (op, UCHARTYPE);
3302 return geniCodeLogic (geniCodeRValue (left, FALSE),
3303 geniCodeRValue (right, FALSE),
3306 return geniCodeConditional (tree);
3309 return operandFromLit (getSize (tree->right->ftype));
3313 sym_link *rtype = operandType (right);
3314 sym_link *ltype = operandType (left);
3315 if (IS_PTR (rtype) && IS_ITEMP (right)
3316 && right->isaddr && checkType (rtype->next, ltype) == 1)
3317 right = geniCodeRValue (right, TRUE);
3319 right = geniCodeRValue (right, FALSE);
3321 geniCodeAssign (left, right, 0);
3326 geniCodeAssign (left,
3327 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3329 geniCodeRValue (right, FALSE), FALSE,FALSE), 0);
3333 geniCodeAssign (left,
3334 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3336 geniCodeRValue (right, FALSE)), 0);
3339 geniCodeAssign (left,
3340 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3342 geniCodeRValue (right, FALSE)), 0);
3345 sym_link *rtype = operandType (right);
3346 sym_link *ltype = operandType (left);
3347 if (IS_PTR (rtype) && IS_ITEMP (right)
3348 && right->isaddr && checkType (rtype->next, ltype) == 1)
3349 right = geniCodeRValue (right, TRUE);
3351 right = geniCodeRValue (right, FALSE);
3354 return geniCodeAssign (left,
3355 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3361 sym_link *rtype = operandType (right);
3362 sym_link *ltype = operandType (left);
3363 if (IS_PTR (rtype) && IS_ITEMP (right)
3364 && right->isaddr && checkType (rtype->next, ltype) == 1)
3366 right = geniCodeRValue (right, TRUE);
3370 right = geniCodeRValue (right, FALSE);
3373 geniCodeAssign (left,
3374 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3380 geniCodeAssign (left,
3381 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3383 geniCodeRValue (right, FALSE)), 0);
3386 geniCodeAssign (left,
3387 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3389 geniCodeRValue (right, FALSE)), 0);
3392 geniCodeAssign (left,
3393 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3395 geniCodeRValue (right, FALSE),
3397 operandType (left)), 0);
3400 geniCodeAssign (left,
3401 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3403 geniCodeRValue (right, FALSE),
3405 operandType (left)), 0);
3408 geniCodeAssign (left,
3409 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3411 geniCodeRValue (right, FALSE),
3413 operandType (left)), 0);
3415 return geniCodeRValue (right, FALSE);
3418 return geniCodeCall (ast2iCode (tree->left),
3421 geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
3422 return ast2iCode (tree->right);
3425 geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
3426 return ast2iCode (tree->right);
3429 geniCodeFunctionBody (tree);
3433 geniCodeReturn (right);
3441 geniCodeSwitch (tree);
3445 geniCodeInline (tree);
3452 /*-----------------------------------------------------------------*/
3453 /* reverseICChain - gets from the list and creates a linkedlist */
3454 /*-----------------------------------------------------------------*/
3461 while ((loop = getSet (&iCodeChain)))
3473 /*-----------------------------------------------------------------*/
3474 /* iCodeFromAst - given an ast will convert it to iCode */
3475 /*-----------------------------------------------------------------*/
3477 iCodeFromAst (ast * tree)
3479 returnLabel = newiTempLabel ("_return");
3480 entryLabel = newiTempLabel ("_entry");
3482 return reverseiCChain ();