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);
1348 /*-----------------------------------------------------------------*/
1349 /* Get size in byte of ptr need to access an array */
1350 /*-----------------------------------------------------------------*/
1352 getArraySizePtr (operand * op)
1354 sym_link *ltype = operandType(op);
1358 int size = getSize(ltype);
1359 return(IS_GENPTR(ltype)?(size-1):size);
1364 sym_link *letype = getSpec(ltype);
1365 switch (PTR_TYPE (SPEC_OCLS (letype)))
1377 return (GPTRSIZE-1);
1386 /*-----------------------------------------------------------------*/
1387 /* perform "usual unary conversions" */
1388 /*-----------------------------------------------------------------*/
1390 usualUnaryConversions (operand * op)
1392 if (IS_INTEGRAL (operandType (op)))
1394 if (getSize (operandType (op)) < INTSIZE)
1397 return geniCodeCast (INTTYPE, op, TRUE);
1403 /*-----------------------------------------------------------------*/
1404 /* perform "usual binary conversions" */
1405 /*-----------------------------------------------------------------*/
1407 usualBinaryConversions (operand ** op1, operand ** op2)
1409 if (!options.ANSIint)
1411 /* "Classic" SDCC behavior. */
1413 sym_link *rtype = operandType (*op2);
1414 sym_link *ltype = operandType (*op1);
1416 ctype = computeType (ltype, rtype);
1417 *op1 = geniCodeCast (ctype, *op1, TRUE);
1418 *op2 = geniCodeCast (ctype, *op2, TRUE);
1423 *op1 = usualUnaryConversions (*op1);
1424 *op2 = usualUnaryConversions (*op2);
1426 /* Try to make the two operands of the same type, following
1427 * the "usual binary conversions" promotion rules.
1429 * NB: floating point types are not yet properly handled; we
1430 * follow the "classic" behavior.
1433 if (IS_FLOAT (operandType (*op1)) || IS_FLOAT (operandType (*op2)))
1435 return newFloatLink ();
1438 if (!IS_INTEGRAL (operandType (*op1)) || !IS_INTEGRAL (operandType (*op2)))
1440 /* if either is not an integer type, we're done. */
1441 return copyLinkChain (operandType (*op1)); /* Punt! we should never get here. */
1444 /* If either is an unsigned long, make sure both are. */
1445 if (SPEC_USIGN (operandType (*op1)) && IS_LONG (operandType (*op1)))
1447 if (!SPEC_USIGN (operandType (*op2)) || !IS_LONG (operandType (*op2)))
1449 *op2 = geniCodeCast (ULONGTYPE, *op2, TRUE);
1451 return copyLinkChain (operandType (*op1));
1454 if (SPEC_USIGN (operandType (*op2)) && IS_LONG (operandType (*op2)))
1456 if (!SPEC_USIGN (operandType (*op1)) || !IS_LONG (operandType (*op1)))
1458 *op1 = geniCodeCast (ULONGTYPE, *op1, TRUE);
1460 return copyLinkChain (operandType (*op2));
1463 /* Next, if one is long and the other is int (signed or un),
1464 * cast both to long.
1466 * Note that because in our environment a long can hold all
1467 * the values of an unsigned int, the "long/unsigned int" pair
1468 * in the ANSI conversion table is unnecessary; this test
1469 * handles that case implicitly.
1471 if (IS_LONG (operandType (*op1)))
1473 /* NB: because of the unary conversions, op2 cannot
1474 * be smaller than int. Therefore, if it is not
1475 * long, it is a regular int.
1477 if (!IS_LONG (operandType (*op2)))
1479 *op2 = geniCodeCast (LONGTYPE, *op2, TRUE);
1481 return copyLinkChain (operandType (*op1));
1484 if (IS_LONG (operandType (*op2)))
1486 /* NB: because of the unary conversions, op2 cannot
1487 * be smaller than int. Therefore, if it is not
1488 * long, it is a regular int.
1490 if (!IS_LONG (operandType (*op1)))
1492 *op1 = geniCodeCast (LONGTYPE, *op1, TRUE);
1494 return copyLinkChain (operandType (*op2));
1497 /* All right, neither is long; they must both be integers.
1499 * Only remaining issue is signed vs. unsigned; if one is unsigned
1500 * and the other isn't, convert both to unsigned.
1502 if (SPEC_USIGN (operandType (*op1)))
1504 if (!SPEC_USIGN (operandType (*op2)))
1506 *op2 = geniCodeCast (UINTTYPE, *op2, TRUE);
1508 return copyLinkChain (operandType (*op1));
1511 if (SPEC_USIGN (operandType (*op2)))
1513 if (!SPEC_USIGN (operandType (*op1)))
1515 *op1 = geniCodeCast (UINTTYPE, *op1, TRUE);
1517 return copyLinkChain (operandType (*op2));
1521 return copyLinkChain (operandType (*op1));
1525 /*-----------------------------------------------------------------*/
1526 /* geniCodeValueAtAddress - generate intermeditate code for value */
1528 /*-----------------------------------------------------------------*/
1530 geniCodeRValue (operand * op, bool force)
1533 sym_link *type = operandType (op);
1534 sym_link *etype = getSpec (type);
1536 /* if this is an array & already */
1537 /* an address then return this */
1538 if (IS_AGGREGATE (type) ||
1539 (IS_PTR (type) && !force && !op->isaddr))
1540 return operandFromOperand (op);
1542 /* if this is not an address then must be */
1543 /* rvalue already so return this one */
1547 /* if this is not a temp symbol then */
1548 if (!IS_ITEMP (op) &&
1550 !IN_FARSPACE (SPEC_OCLS (etype)))
1552 op = operandFromOperand (op);
1557 if (IS_SPEC (type) &&
1558 IS_TRUE_SYMOP (op) &&
1559 (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
1561 op = operandFromOperand (op);
1566 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1567 if (IS_PTR (type) && op->isaddr && force)
1570 type = copyLinkChain (type);
1572 IC_RESULT (ic) = newiTempOperand (type, 1);
1573 IC_RESULT (ic)->isaddr = 0;
1575 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1577 /* if the right is a symbol */
1578 if (op->type == SYMBOL)
1579 IC_RESULT (ic)->operand.symOperand->args =
1580 op->operand.symOperand->args;
1583 return IC_RESULT (ic);
1586 /*-----------------------------------------------------------------*/
1587 /* geniCodeCast - changes the value from one type to another */
1588 /*-----------------------------------------------------------------*/
1590 geniCodeCast (sym_link * type, operand * op, bool implicit)
1594 sym_link *opetype = getSpec (optype = operandType (op));
1597 /* one of them has size zero then error */
1598 if (IS_VOID (optype))
1600 werror (E_CAST_ZERO);
1604 /* if the operand is already the desired type then do nothing */
1605 if (checkType (type, optype) == 1)
1608 /* if this is a literal then just change the type & return */
1609 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1610 return operandFromValue (valCastLiteral (type,
1611 operandLitValue (op)));
1613 /* if casting to some pointer type &&
1614 the destination is not a generic pointer
1615 then give a warning : (only for implicit casts) */
1616 if (IS_PTR (optype) && implicit &&
1617 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1620 werror (E_INCOMPAT_CAST);
1621 werror (E_CONTINUE, "from type '");
1622 printTypeChain (optype, stderr);
1623 fprintf (stderr, "' to type '");
1624 printTypeChain (type, stderr);
1625 fprintf (stderr, "'\n");
1628 /* if they are the same size create an assignment */
1629 if (getSize (type) == getSize (optype) &&
1630 !IS_BITFIELD (type) &&
1632 !IS_FLOAT (optype) &&
1633 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1634 (!IS_SPEC (type) && !IS_SPEC (optype))))
1637 ic = newiCode ('=', NULL, op);
1638 IC_RESULT (ic) = newiTempOperand (type, 0);
1639 SPIL_LOC (IC_RESULT (ic)) =
1640 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1641 IC_RESULT (ic)->isaddr = 0;
1645 ic = newiCode (CAST, operandFromLink (type),
1646 geniCodeRValue (op, FALSE));
1648 IC_RESULT (ic) = newiTempOperand (type, 0);
1651 /* preserve the storage class & output class */
1652 /* of the original variable */
1653 restype = getSpec (operandType (IC_RESULT (ic)));
1654 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1655 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1658 return IC_RESULT (ic);
1661 /*-----------------------------------------------------------------*/
1662 /* geniCodeLabel - will create a Label */
1663 /*-----------------------------------------------------------------*/
1665 geniCodeLabel (symbol * label)
1669 ic = newiCodeLabelGoto (LABEL, label);
1673 /*-----------------------------------------------------------------*/
1674 /* geniCodeGoto - will create a Goto */
1675 /*-----------------------------------------------------------------*/
1677 geniCodeGoto (symbol * label)
1681 ic = newiCodeLabelGoto (GOTO, label);
1685 /*-----------------------------------------------------------------*/
1686 /* geniCodeMultiply - gen intermediate code for multiplication */
1687 /*-----------------------------------------------------------------*/
1689 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1697 /* if they are both literal then we know the result */
1698 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1699 return operandFromValue (valMult (left->operand.valOperand,
1700 right->operand.valOperand));
1704 saveOption = options.ANSIint;
1705 options.ANSIint = 0;
1707 resType = usualBinaryConversions (&left, &right);
1710 options.ANSIint = saveOption;
1711 SPEC_NOUN(getSpec(resType))=V_INT;
1712 SPEC_SHORT(getSpec(resType))=0;
1715 /* if the right is a literal & power of 2 */
1716 /* then make it a left shift */
1717 /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
1718 /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
1719 if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
1720 !((resultIsInt) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
1721 (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
1723 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1725 /* LEFT_OP need same size for left and result, */
1726 left = geniCodeCast (resType, left, TRUE);
1727 ltype = operandType (left);
1729 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1733 ic = newiCode ('*', left, right); /* normal multiplication */
1734 /* if the size left or right > 1 then support routine */
1735 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1739 IC_RESULT (ic) = newiTempOperand (resType, 1);
1742 return IC_RESULT (ic);
1745 /*-----------------------------------------------------------------*/
1746 /* geniCodeDivision - gen intermediate code for division */
1747 /*-----------------------------------------------------------------*/
1749 geniCodeDivision (operand * left, operand * right)
1754 sym_link *rtype = operandType (right);
1755 sym_link *retype = getSpec (rtype);
1756 sym_link *ltype = operandType (left);
1757 sym_link *letype = getSpec (ltype);
1759 resType = usualBinaryConversions (&left, &right);
1761 /* if the right is a literal & power of 2 */
1762 /* then make it a right shift */
1763 if (IS_LITERAL (retype) &&
1764 !IS_FLOAT (letype) &&
1765 (p2 = powof2 ((unsigned long)
1766 floatFromVal (right->operand.valOperand))))
1767 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1770 ic = newiCode ('/', left, right); /* normal division */
1771 /* if the size left or right > 1 then support routine */
1772 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1775 IC_RESULT (ic) = newiTempOperand (resType, 0);
1778 return IC_RESULT (ic);
1780 /*-----------------------------------------------------------------*/
1781 /* geniCodeModulus - gen intermediate code for modulus */
1782 /*-----------------------------------------------------------------*/
1784 geniCodeModulus (operand * left, operand * right)
1790 /* if they are both literal then we know the result */
1791 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1792 return operandFromValue (valMod (left->operand.valOperand,
1793 right->operand.valOperand));
1795 resType = usualBinaryConversions (&left, &right);
1797 /* now they are the same size */
1798 ic = newiCode ('%', left, right);
1800 /* if the size left or right > 1 then support routine */
1801 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1803 IC_RESULT (ic) = newiTempOperand (resType, 0);
1806 return IC_RESULT (ic);
1809 /*-----------------------------------------------------------------*/
1810 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1811 /*-----------------------------------------------------------------*/
1813 geniCodePtrPtrSubtract (operand * left, operand * right)
1819 /* if they are both literals then */
1820 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1822 result = operandFromValue (valMinus (left->operand.valOperand,
1823 right->operand.valOperand));
1827 ic = newiCode ('-', left, right);
1829 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1833 return geniCodeDivision (result,
1834 operandFromLit (getSize (ltype->next)));
1837 /*-----------------------------------------------------------------*/
1838 /* geniCodeSubtract - generates code for subtraction */
1839 /*-----------------------------------------------------------------*/
1841 geniCodeSubtract (operand * left, operand * right)
1848 /* if they both pointers then */
1849 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1850 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1851 return geniCodePtrPtrSubtract (left, right);
1853 /* if they are both literal then we know the result */
1854 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1855 && left->isLiteral && right->isLiteral)
1856 return operandFromValue (valMinus (left->operand.valOperand,
1857 right->operand.valOperand));
1859 /* if left is an array or pointer */
1860 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1862 isarray = left->isaddr;
1863 right = geniCodeMultiply (right,
1864 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) == INTSIZE));
1865 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1868 { /* make them the same size */
1869 resType = usualBinaryConversions (&left, &right);
1872 ic = newiCode ('-', left, right);
1874 IC_RESULT (ic) = newiTempOperand (resType, 1);
1875 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1877 /* if left or right is a float */
1878 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1882 return IC_RESULT (ic);
1885 /*-----------------------------------------------------------------*/
1886 /* geniCodeAdd - generates iCode for addition */
1887 /*-----------------------------------------------------------------*/
1889 geniCodeAdd (operand * left, operand * right)
1897 /* if left is an array then array access */
1898 if (IS_ARRAY (ltype))
1899 return geniCodeArray (left, right);
1901 /* if the right side is LITERAL zero */
1902 /* return the left side */
1903 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1906 /* if left is literal zero return right */
1907 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1910 /* if left is an array or pointer then size */
1913 isarray = left->isaddr;
1914 size = operandFromLit (getSize (ltype->next));
1915 right = geniCodeMultiply (right, size, (getArraySizePtr(left) == INTSIZE));
1916 resType = copyLinkChain (ltype);
1919 { /* make them the same size */
1920 resType = usualBinaryConversions (&left, &right);
1923 /* if they are both literals then we know */
1924 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1925 && left->isLiteral && right->isLiteral)
1926 return operandFromValue (valPlus (valFromType (letype),
1927 valFromType (retype)));
1929 ic = newiCode ('+', left, right);
1931 IC_RESULT (ic) = newiTempOperand (resType, 1);
1932 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1934 /* if left or right is a float then support
1936 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1941 return IC_RESULT (ic);
1945 /*-----------------------------------------------------------------*/
1946 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1947 /*-----------------------------------------------------------------*/
1949 aggrToPtr (sym_link * type, bool force)
1955 if (IS_PTR (type) && !force)
1958 etype = getSpec (type);
1962 /* if the output class is generic */
1963 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1964 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1966 /* if the variable was declared a constant */
1967 /* then the pointer points to a constant */
1968 if (IS_CONSTANT (etype))
1969 DCL_PTR_CONST (ptype) = 1;
1971 /* the variable was volatile then pointer to volatile */
1972 if (IS_VOLATILE (etype))
1973 DCL_PTR_VOLATILE (ptype) = 1;
1977 /*-----------------------------------------------------------------*/
1978 /* geniCodeArray2Ptr - array to pointer */
1979 /*-----------------------------------------------------------------*/
1981 geniCodeArray2Ptr (operand * op)
1983 sym_link *optype = operandType (op);
1984 sym_link *opetype = getSpec (optype);
1986 /* set the pointer depending on the storage class */
1987 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1988 DCL_PTR_CONST (optype) = port->mem.code_ro;
1991 /* if the variable was declared a constant */
1992 /* then the pointer points to a constant */
1993 if (IS_CONSTANT (opetype))
1994 DCL_PTR_CONST (optype) = 1;
1996 /* the variable was volatile then pointer to volatile */
1997 if (IS_VOLATILE (opetype))
1998 DCL_PTR_VOLATILE (optype) = 1;
2004 /*-----------------------------------------------------------------*/
2005 /* geniCodeArray - array access */
2006 /*-----------------------------------------------------------------*/
2008 geniCodeArray (operand * left, operand * right)
2011 sym_link *ltype = operandType (left);
2015 if (IS_PTR (ltype->next) && left->isaddr)
2017 left = geniCodeRValue (left, FALSE);
2019 return geniCodeDerefPtr (geniCodeAdd (left, right));
2022 right = geniCodeMultiply (right,
2023 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) == INTSIZE));
2025 /* we can check for limits here */
2026 if (isOperandLiteral (right) &&
2029 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2031 werror (E_ARRAY_BOUND);
2032 right = operandFromLit (0);
2035 ic = newiCode ('+', left, right);
2037 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2038 !IS_AGGREGATE (ltype->next) &&
2039 !IS_PTR (ltype->next))
2040 ? ltype : ltype->next), 0);
2042 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2044 return IC_RESULT (ic);
2047 /*-----------------------------------------------------------------*/
2048 /* geniCodeStruct - generates intermediate code for structres */
2049 /*-----------------------------------------------------------------*/
2051 geniCodeStruct (operand * left, operand * right, bool islval)
2054 sym_link *type = operandType (left);
2055 sym_link *etype = getSpec (type);
2057 symbol *element = getStructElement (SPEC_STRUCT (etype),
2058 right->operand.symOperand);
2060 /* add the offset */
2061 ic = newiCode ('+', left, operandFromLit (element->offset));
2063 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2065 /* preserve the storage & output class of the struct */
2066 /* as well as the volatile attribute */
2067 retype = getSpec (operandType (IC_RESULT (ic)));
2068 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2069 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2070 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2072 if (IS_PTR (element->type))
2073 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2075 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2079 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2082 /*-----------------------------------------------------------------*/
2083 /* geniCodePostInc - generate int code for Post increment */
2084 /*-----------------------------------------------------------------*/
2086 geniCodePostInc (operand * op)
2090 sym_link *optype = operandType (op);
2092 operand *rv = (IS_ITEMP (op) ?
2093 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2095 sym_link *rvtype = operandType (rv);
2098 /* if this is not an address we have trouble */
2101 werror (E_LVALUE_REQUIRED, "++");
2105 rOp = newiTempOperand (rvtype, 0);
2111 geniCodeAssign (rOp, rv, 0);
2113 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2114 if (IS_FLOAT (rvtype))
2115 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2117 ic = newiCode ('+', rv, operandFromLit (size));
2119 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2122 geniCodeAssign (op, result, 0);
2128 /*-----------------------------------------------------------------*/
2129 /* geniCodePreInc - generate code for preIncrement */
2130 /*-----------------------------------------------------------------*/
2132 geniCodePreInc (operand * op)
2135 sym_link *optype = operandType (op);
2136 operand *rop = (IS_ITEMP (op) ?
2137 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2139 sym_link *roptype = operandType (rop);
2145 werror (E_LVALUE_REQUIRED, "++");
2150 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2151 if (IS_FLOAT (roptype))
2152 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2154 ic = newiCode ('+', rop, operandFromLit (size));
2155 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2159 return geniCodeAssign (op, result, 0);
2162 /*-----------------------------------------------------------------*/
2163 /* geniCodePostDec - generates code for Post decrement */
2164 /*-----------------------------------------------------------------*/
2166 geniCodePostDec (operand * op)
2170 sym_link *optype = operandType (op);
2172 operand *rv = (IS_ITEMP (op) ?
2173 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2175 sym_link *rvtype = operandType (rv);
2178 /* if this is not an address we have trouble */
2181 werror (E_LVALUE_REQUIRED, "++");
2185 rOp = newiTempOperand (rvtype, 0);
2191 geniCodeAssign (rOp, rv, 0);
2193 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2194 if (IS_FLOAT (rvtype))
2195 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2197 ic = newiCode ('-', rv, operandFromLit (size));
2199 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2202 geniCodeAssign (op, result, 0);
2208 /*-----------------------------------------------------------------*/
2209 /* geniCodePreDec - generate code for pre decrement */
2210 /*-----------------------------------------------------------------*/
2212 geniCodePreDec (operand * op)
2215 sym_link *optype = operandType (op);
2216 operand *rop = (IS_ITEMP (op) ?
2217 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2219 sym_link *roptype = operandType (rop);
2225 werror (E_LVALUE_REQUIRED, "++");
2230 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2231 if (IS_FLOAT (roptype))
2232 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2234 ic = newiCode ('-', rop, operandFromLit (size));
2235 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2239 return geniCodeAssign (op, result, 0);
2243 /*-----------------------------------------------------------------*/
2244 /* geniCodeBitwise - gen int code for bitWise operators */
2245 /*-----------------------------------------------------------------*/
2247 geniCodeBitwise (operand * left, operand * right,
2248 int oper, sym_link * resType)
2252 left = geniCodeCast (resType, left, TRUE);
2253 right = geniCodeCast (resType, right, TRUE);
2255 ic = newiCode (oper, left, right);
2256 IC_RESULT (ic) = newiTempOperand (resType, 0);
2259 return IC_RESULT (ic);
2262 /*-----------------------------------------------------------------*/
2263 /* geniCodeAddressOf - gens icode for '&' address of operator */
2264 /*-----------------------------------------------------------------*/
2266 geniCodeAddressOf (operand * op)
2270 sym_link *optype = operandType (op);
2271 sym_link *opetype = getSpec (optype);
2273 /* lvalue check already done in decorateType */
2274 /* this must be a lvalue */
2275 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2276 /* werror (E_LVALUE_REQUIRED,"&"); */
2281 p->class = DECLARATOR;
2283 /* set the pointer depending on the storage class */
2284 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2285 DCL_PTR_CONST (p) = port->mem.code_ro;
2287 /* make sure we preserve the const & volatile */
2288 if (IS_CONSTANT (opetype))
2289 DCL_PTR_CONST (p) = 1;
2291 if (IS_VOLATILE (opetype))
2292 DCL_PTR_VOLATILE (p) = 1;
2294 p->next = copyLinkChain (optype);
2296 /* if already a temp */
2299 setOperandType (op, p);
2304 /* other wise make this of the type coming in */
2305 ic = newiCode (ADDRESS_OF, op, NULL);
2306 IC_RESULT (ic) = newiTempOperand (p, 1);
2307 IC_RESULT (ic)->isaddr = 0;
2309 return IC_RESULT (ic);
2311 /*-----------------------------------------------------------------*/
2312 /* setOClass - sets the output class depending on the pointer type */
2313 /*-----------------------------------------------------------------*/
2315 setOClass (sym_link * ptr, sym_link * spec)
2317 switch (DCL_TYPE (ptr))
2320 SPEC_OCLS (spec) = data;
2324 SPEC_OCLS (spec) = generic;
2328 SPEC_OCLS (spec) = xdata;
2332 SPEC_OCLS (spec) = code;
2336 SPEC_OCLS (spec) = idata;
2340 SPEC_OCLS (spec) = xstack;
2344 SPEC_OCLS (spec) = eeprom;
2353 /*-----------------------------------------------------------------*/
2354 /* geniCodeDerefPtr - dereference pointer with '*' */
2355 /*-----------------------------------------------------------------*/
2357 geniCodeDerefPtr (operand * op)
2359 sym_link *rtype, *retype;
2360 sym_link *optype = operandType (op);
2362 /* if this is a pointer then generate the rvalue */
2363 if (IS_PTR (optype))
2365 if (IS_TRUE_SYMOP (op))
2368 op = geniCodeRValue (op, TRUE);
2371 op = geniCodeRValue (op, TRUE);
2374 /* now get rid of the pointer part */
2375 if (lvaluereq && IS_ITEMP (op))
2377 retype = getSpec (rtype = copyLinkChain (optype));
2381 retype = getSpec (rtype = copyLinkChain (optype->next));
2384 /* if this is a pointer then outputclass needs 2b updated */
2385 if (IS_PTR (optype))
2386 setOClass (optype, retype);
2388 op->isGptr = IS_GENPTR (optype);
2390 /* if the pointer was declared as a constant */
2391 /* then we cannot allow assignment to the derefed */
2392 if (IS_PTR_CONST (optype))
2393 SPEC_CONST (retype) = 1;
2395 op->isaddr = (IS_PTR (rtype) ||
2396 IS_STRUCT (rtype) ||
2402 op = geniCodeRValue (op, TRUE);
2404 setOperandType (op, rtype);
2409 /*-----------------------------------------------------------------*/
2410 /* geniCodeUnaryMinus - does a unary minus of the operand */
2411 /*-----------------------------------------------------------------*/
2413 geniCodeUnaryMinus (operand * op)
2416 sym_link *optype = operandType (op);
2418 if (IS_LITERAL (optype))
2419 return operandFromLit (-floatFromVal (op->operand.valOperand));
2421 ic = newiCode (UNARYMINUS, op, NULL);
2422 IC_RESULT (ic) = newiTempOperand (optype, 0);
2424 return IC_RESULT (ic);
2427 /*-----------------------------------------------------------------*/
2428 /* geniCodeLeftShift - gen i code for left shift */
2429 /*-----------------------------------------------------------------*/
2431 geniCodeLeftShift (operand * left, operand * right)
2436 /* Note that we don't use the usual binary conversions for the
2437 * shift operations, in accordance with our ANSI friends.
2439 if (options.ANSIint)
2441 right = usualUnaryConversions (right);
2442 left = usualUnaryConversions (left);
2445 ic = newiCode (LEFT_OP, left, right);
2446 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2448 return IC_RESULT (ic);
2451 /*-----------------------------------------------------------------*/
2452 /* geniCodeRightShift - gen i code for right shift */
2453 /*-----------------------------------------------------------------*/
2455 geniCodeRightShift (operand * left, operand * right)
2460 /* Note that we don't use the usual binary conversions for the
2461 * shift operations, in accordance with our ANSI friends.
2463 if (options.ANSIint)
2465 right = usualUnaryConversions (right);
2466 left = usualUnaryConversions (left);
2469 ic = newiCode (RIGHT_OP, left, right);
2470 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2472 return IC_RESULT (ic);
2475 #if defined(__BORLANDC__) || defined(_MSC_VER)
2476 #define LONG_LONG __int64
2478 #define LONG_LONG long long
2481 /*-----------------------------------------------------------------*/
2482 /* geniCodeLogic- logic code */
2483 /*-----------------------------------------------------------------*/
2485 geniCodeLogic (operand * left, operand * right, int op)
2489 sym_link *rtype = operandType (right);
2490 sym_link *ltype = operandType (left);
2492 /* left is integral type and right is literal then
2493 check if the literal value is within bounds */
2494 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2496 int nbits = bitsForType (ltype);
2497 long v = operandLitValue (right);
2499 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2500 werror (W_CONST_RANGE, " compare operation ");
2503 ctype = usualBinaryConversions (&left, &right);
2505 ic = newiCode (op, left, right);
2506 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2508 /* if comparing anything greater than one byte
2509 and not a '==' || '!=' || '&&' || '||' (these
2511 if (getSize (ctype) > 1 &&
2519 return IC_RESULT (ic);
2522 /*-----------------------------------------------------------------*/
2523 /* geniCodeUnary - for a a generic unary operation */
2524 /*-----------------------------------------------------------------*/
2526 geniCodeUnary (operand * op, int oper)
2528 iCode *ic = newiCode (oper, op, NULL);
2530 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2532 return IC_RESULT (ic);
2535 /*-----------------------------------------------------------------*/
2536 /* geniCodeConditional - geniCode for '?' ':' operation */
2537 /*-----------------------------------------------------------------*/
2539 geniCodeConditional (ast * tree)
2542 symbol *falseLabel = newiTempLabel (NULL);
2543 symbol *exitLabel = newiTempLabel (NULL);
2544 operand *cond = ast2iCode (tree->left);
2545 operand *true, *false, *result;
2547 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2551 true = ast2iCode (tree->right->left);
2553 /* move the value to a new Operand */
2554 result = newiTempOperand (operandType (true), 0);
2555 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2557 /* generate an unconditional goto */
2558 geniCodeGoto (exitLabel);
2560 /* now for the right side */
2561 geniCodeLabel (falseLabel);
2563 false = ast2iCode (tree->right->right);
2564 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2566 /* create the exit label */
2567 geniCodeLabel (exitLabel);
2572 /*-----------------------------------------------------------------*/
2573 /* geniCodeAssign - generate code for assignment */
2574 /*-----------------------------------------------------------------*/
2576 geniCodeAssign (operand * left, operand * right, int nosupdate)
2579 sym_link *ltype = operandType (left);
2580 sym_link *rtype = operandType (right);
2582 if (!left->isaddr && !IS_ITEMP (left))
2584 werror (E_LVALUE_REQUIRED, "assignment");
2588 /* left is integral type and right is literal then
2589 check if the literal value is within bounds */
2590 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2592 int nbits = bitsForType (ltype);
2593 long v = operandLitValue (right);
2595 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2596 werror (W_CONST_RANGE, " = operation");
2599 /* if the left & right type don't exactly match */
2600 /* if pointer set then make sure the check is
2601 done with the type & not the pointer */
2602 /* then cast rights type to left */
2604 /* first check the type for pointer assignement */
2605 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2606 checkType (ltype, rtype) < 0)
2608 if (checkType (ltype->next, rtype) < 0)
2609 right = geniCodeCast (ltype->next, right, TRUE);
2611 else if (checkType (ltype, rtype) < 0)
2612 right = geniCodeCast (ltype, right, TRUE);
2614 /* if left is a true symbol & ! volatile
2615 create an assignment to temporary for
2616 the right & then assign this temporary
2617 to the symbol this is SSA . isn't it simple
2618 and folks have published mountains of paper on it */
2619 if (IS_TRUE_SYMOP (left) &&
2620 !isOperandVolatile (left, FALSE) &&
2621 isOperandGlobal (left))
2625 if (IS_TRUE_SYMOP (right))
2626 sym = OP_SYMBOL (right);
2627 ic = newiCode ('=', NULL, right);
2628 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2629 SPIL_LOC (right) = sym;
2633 ic = newiCode ('=', NULL, right);
2634 IC_RESULT (ic) = left;
2637 /* if left isgptr flag is set then support
2638 routine will be required */
2642 ic->nosupdate = nosupdate;
2646 /*-----------------------------------------------------------------*/
2647 /* geniCodeSEParms - generate code for side effecting fcalls */
2648 /*-----------------------------------------------------------------*/
2650 geniCodeSEParms (ast * parms)
2655 if (parms->type == EX_OP && parms->opval.op == PARAM)
2657 geniCodeSEParms (parms->left);
2658 geniCodeSEParms (parms->right);
2662 /* hack don't like this but too lazy to think of
2664 if (IS_ADDRESS_OF_OP (parms))
2665 parms->left->lvalue = 1;
2667 if (IS_CAST_OP (parms) &&
2668 IS_PTR (parms->ftype) &&
2669 IS_ADDRESS_OF_OP (parms->right))
2670 parms->right->left->lvalue = 1;
2672 parms->opval.oprnd =
2673 geniCodeRValue (ast2iCode (parms), FALSE);
2675 parms->type = EX_OPERAND;
2678 /*-----------------------------------------------------------------*/
2679 /* geniCodeParms - generates parameters */
2680 /*-----------------------------------------------------------------*/
2682 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
2690 /* if this is a param node then do the left & right */
2691 if (parms->type == EX_OP && parms->opval.op == PARAM)
2693 geniCodeParms (parms->left, stack, fetype, func);
2694 geniCodeParms (parms->right, stack, fetype, func);
2698 /* get the parameter value */
2699 if (parms->type == EX_OPERAND)
2700 pval = parms->opval.oprnd;
2703 /* maybe this else should go away ?? */
2704 /* hack don't like this but too lazy to think of
2706 if (IS_ADDRESS_OF_OP (parms))
2707 parms->left->lvalue = 1;
2709 if (IS_CAST_OP (parms) &&
2710 IS_PTR (parms->ftype) &&
2711 IS_ADDRESS_OF_OP (parms->right))
2712 parms->right->left->lvalue = 1;
2714 pval = geniCodeRValue (ast2iCode (parms), FALSE);
2717 /* if register parm then make it a send */
2718 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2719 IS_REGPARM (parms->etype)) && !func->hasVargs)
2721 ic = newiCode (SEND, pval, NULL);
2726 /* now decide whether to push or assign */
2727 if (!(options.stackAuto || IS_RENT (fetype)))
2731 operand *top = operandFromSymbol (parms->argSym);
2732 geniCodeAssign (top, pval, 1);
2736 sym_link *p = operandType (pval);
2738 ic = newiCode (IPUSH, pval, NULL);
2740 /* update the stack adjustment */
2741 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2748 /*-----------------------------------------------------------------*/
2749 /* geniCodeCall - generates temp code for calling */
2750 /*-----------------------------------------------------------------*/
2752 geniCodeCall (operand * left, ast * parms)
2756 sym_link *type, *etype;
2759 /* take care of parameters with side-effecting
2760 function calls in them, this is required to take care
2761 of overlaying function parameters */
2762 geniCodeSEParms (parms);
2764 /* first the parameters */
2765 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
2767 /* now call : if symbol then pcall */
2768 if (IS_OP_POINTER (left))
2769 ic = newiCode (PCALL, left, NULL);
2771 ic = newiCode (CALL, left, NULL);
2773 IC_ARGS (ic) = left->operand.symOperand->args;
2774 type = copyLinkChain (operandType (left)->next);
2775 etype = getSpec (type);
2776 SPEC_EXTR (etype) = 0;
2777 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2781 /* stack adjustment after call */
2782 ic->parmBytes = stack;
2787 /*-----------------------------------------------------------------*/
2788 /* geniCodeReceive - generate intermediate code for "receive" */
2789 /*-----------------------------------------------------------------*/
2791 geniCodeReceive (value * args)
2793 /* for all arguments that are passed in registers */
2797 if (IS_REGPARM (args->etype))
2799 operand *opr = operandFromValue (args);
2801 symbol *sym = OP_SYMBOL (opr);
2804 /* we will use it after all optimizations
2805 and before liveRange calculation */
2806 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2809 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2810 options.stackAuto == 0 &&
2816 opl = newiTempOperand (args->type, 0);
2818 sym->reqv->key = sym->key;
2819 OP_SYMBOL (sym->reqv)->key = sym->key;
2820 OP_SYMBOL (sym->reqv)->isreqv = 1;
2821 OP_SYMBOL (sym->reqv)->islocal = 0;
2822 SPIL_LOC (sym->reqv) = sym;
2826 ic = newiCode (RECEIVE, NULL, NULL);
2827 currFunc->recvSize = getSize (sym->etype);
2828 IC_RESULT (ic) = opr;
2836 /*-----------------------------------------------------------------*/
2837 /* geniCodeFunctionBody - create the function body */
2838 /*-----------------------------------------------------------------*/
2840 geniCodeFunctionBody (ast * tree)
2847 /* reset the auto generation */
2853 func = ast2iCode (tree->left);
2854 fetype = getSpec (operandType (func));
2856 savelineno = lineno;
2857 lineno = OP_SYMBOL (func)->lineDef;
2858 /* create an entry label */
2859 geniCodeLabel (entryLabel);
2860 lineno = savelineno;
2862 /* create a proc icode */
2863 ic = newiCode (FUNCTION, func, NULL);
2864 /* if the function has parmas then */
2865 /* save the parameters information */
2866 ic->argLabel.args = tree->values.args;
2867 ic->lineno = OP_SYMBOL (func)->lineDef;
2871 /* for all parameters that are passed
2872 on registers add a "receive" */
2873 geniCodeReceive (tree->values.args);
2875 /* generate code for the body */
2876 ast2iCode (tree->right);
2878 /* create a label for return */
2879 geniCodeLabel (returnLabel);
2881 /* now generate the end proc */
2882 ic = newiCode (ENDFUNCTION, func, NULL);
2887 /*-----------------------------------------------------------------*/
2888 /* geniCodeReturn - gen icode for 'return' statement */
2889 /*-----------------------------------------------------------------*/
2891 geniCodeReturn (operand * op)
2895 /* if the operand is present force an rvalue */
2897 op = geniCodeRValue (op, FALSE);
2899 ic = newiCode (RETURN, op, NULL);
2903 /*-----------------------------------------------------------------*/
2904 /* geniCodeIfx - generates code for extended if statement */
2905 /*-----------------------------------------------------------------*/
2907 geniCodeIfx (ast * tree)
2910 operand *condition = ast2iCode (tree->left);
2913 /* if condition is null then exit */
2917 condition = geniCodeRValue (condition, FALSE);
2919 cetype = getSpec (operandType (condition));
2920 /* if the condition is a literal */
2921 if (IS_LITERAL (cetype))
2923 if (floatFromVal (condition->operand.valOperand))
2925 if (tree->trueLabel)
2926 geniCodeGoto (tree->trueLabel);
2932 if (tree->falseLabel)
2933 geniCodeGoto (tree->falseLabel);
2940 if (tree->trueLabel)
2942 ic = newiCodeCondition (condition,
2947 if (tree->falseLabel)
2948 geniCodeGoto (tree->falseLabel);
2952 ic = newiCodeCondition (condition,
2959 ast2iCode (tree->right);
2962 /*-----------------------------------------------------------------*/
2963 /* geniCodeJumpTable - tries to create a jump table for switch */
2964 /*-----------------------------------------------------------------*/
2966 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2968 int min = 0, max = 0, t, cnt = 0;
2975 if (!tree || !caseVals)
2978 /* the criteria for creating a jump table is */
2979 /* all integer numbers between the maximum & minimum must */
2980 /* be present , the maximum value should not exceed 255 */
2981 min = max = (int) floatFromVal (vch = caseVals);
2982 sprintf (buffer, "_case_%d_%d",
2983 tree->values.switchVals.swNum,
2985 addSet (&labels, newiTempLabel (buffer));
2987 /* if there is only one case value then no need */
2988 if (!(vch = vch->next))
2993 if (((t = (int) floatFromVal (vch)) - max) != 1)
2995 sprintf (buffer, "_case_%d_%d",
2996 tree->values.switchVals.swNum,
2998 addSet (&labels, newiTempLabel (buffer));
3004 /* if the number of case statements <= 2 then */
3005 /* it is not economical to create the jump table */
3006 /* since two compares are needed for boundary conditions */
3007 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3010 if (tree->values.switchVals.swDefault)
3011 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3013 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3015 falseLabel = newiTempLabel (buffer);
3017 /* so we can create a jumptable */
3018 /* first we rule out the boundary conditions */
3019 /* if only optimization says so */
3020 if (!optimize.noJTabBoundary)
3022 sym_link *cetype = getSpec (operandType (cond));
3023 /* no need to check the lower bound if
3024 the condition is unsigned & minimum value is zero */
3025 if (!(min == 0 && SPEC_USIGN (cetype)))
3027 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3028 ic = newiCodeCondition (boundary, falseLabel, NULL);
3032 /* now for upper bounds */
3033 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3034 ic = newiCodeCondition (boundary, falseLabel, NULL);
3038 /* if the min is not zero then we no make it zero */
3041 cond = geniCodeSubtract (cond, operandFromLit (min));
3042 setOperandType (cond, UCHARTYPE);
3045 /* now create the jumptable */
3046 ic = newiCode (JUMPTABLE, NULL, NULL);
3047 IC_JTCOND (ic) = cond;
3048 IC_JTLABELS (ic) = labels;
3053 /*-----------------------------------------------------------------*/
3054 /* geniCodeSwitch - changes a switch to a if statement */
3055 /*-----------------------------------------------------------------*/
3057 geniCodeSwitch (ast * tree)
3060 operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
3061 value *caseVals = tree->values.switchVals.swVals;
3062 symbol *trueLabel, *falseLabel;
3064 /* if we can make this a jump table */
3065 if (geniCodeJumpTable (cond, caseVals, tree))
3066 goto jumpTable; /* no need for the comparison */
3068 /* for the cases defined do */
3072 operand *compare = geniCodeLogic (cond,
3073 operandFromValue (caseVals),
3076 sprintf (buffer, "_case_%d_%d",
3077 tree->values.switchVals.swNum,
3078 (int) floatFromVal (caseVals));
3079 trueLabel = newiTempLabel (buffer);
3081 ic = newiCodeCondition (compare, trueLabel, NULL);
3083 caseVals = caseVals->next;
3088 /* if default is present then goto break else break */
3089 if (tree->values.switchVals.swDefault)
3090 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3092 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3094 falseLabel = newiTempLabel (buffer);
3095 geniCodeGoto (falseLabel);
3098 ast2iCode (tree->right);
3101 /*-----------------------------------------------------------------*/
3102 /* geniCodeInline - intermediate code for inline assembler */
3103 /*-----------------------------------------------------------------*/
3105 geniCodeInline (ast * tree)
3109 ic = newiCode (INLINEASM, NULL, NULL);
3110 IC_INLINE (ic) = tree->values.inlineasm;
3114 /*-----------------------------------------------------------------*/
3115 /* ast2iCode - creates an icodeList from an ast */
3116 /*-----------------------------------------------------------------*/
3118 ast2iCode (ast * tree)
3120 operand *left = NULL;
3121 operand *right = NULL;
3126 /* set the global variables for filename & line number */
3128 filename = tree->filename;
3130 lineno = tree->lineno;
3132 block = tree->block;
3134 scopeLevel = tree->level;
3136 if (tree->type == EX_VALUE)
3137 return operandFromValue (tree->opval.val);
3139 if (tree->type == EX_LINK)
3140 return operandFromLink (tree->opval.lnk);
3142 /* if we find a nullop */
3143 if (tree->type == EX_OP &&
3144 (tree->opval.op == NULLOP ||
3145 tree->opval.op == BLOCK))
3147 ast2iCode (tree->left);
3148 ast2iCode (tree->right);
3152 /* special cases for not evaluating */
3153 if (tree->opval.op != ':' &&
3154 tree->opval.op != '?' &&
3155 tree->opval.op != CALL &&
3156 tree->opval.op != IFX &&
3157 tree->opval.op != LABEL &&
3158 tree->opval.op != GOTO &&
3159 tree->opval.op != SWITCH &&
3160 tree->opval.op != FUNCTION &&
3161 tree->opval.op != INLINEASM)
3164 if (IS_ASSIGN_OP (tree->opval.op) ||
3165 IS_DEREF_OP (tree) ||
3166 (tree->opval.op == '&' && !tree->right) ||
3167 tree->opval.op == PTR_OP)
3170 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3171 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3173 int olvr = lvaluereq;
3175 left = operandFromAst (tree->left);
3176 lvaluereq = olvr - 1;
3180 left = operandFromAst (tree->left);
3183 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3184 left = geniCodeRValue (left, TRUE);
3188 left = operandFromAst (tree->left);
3190 if (tree->opval.op == INC_OP ||
3191 tree->opval.op == DEC_OP)
3194 right = operandFromAst (tree->right);
3199 right = operandFromAst (tree->right);
3203 /* now depending on the type of operand */
3204 /* this will be a biggy */
3205 switch (tree->opval.op)
3208 case '[': /* array operation */
3210 sym_link *ltype = operandType (left);
3211 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3212 right = geniCodeRValue (right, TRUE);
3215 return geniCodeArray (left, right);
3217 case '.': /* structure dereference */
3218 if (IS_PTR (operandType (left)))
3219 left = geniCodeRValue (left, TRUE);
3221 left = geniCodeRValue (left, FALSE);
3223 return geniCodeStruct (left, right, tree->lvalue);
3225 case PTR_OP: /* structure pointer dereference */
3228 pType = operandType (left);
3229 left = geniCodeRValue (left, TRUE);
3231 setOClass (pType, getSpec (operandType (left)));
3234 return geniCodeStruct (left, right, tree->lvalue);
3236 case INC_OP: /* increment operator */
3238 return geniCodePostInc (left);
3240 return geniCodePreInc (right);
3242 case DEC_OP: /* decrement operator */
3244 return geniCodePostDec (left);
3246 return geniCodePreDec (right);
3248 case '&': /* bitwise and or address of operator */
3250 { /* this is a bitwise operator */
3251 left = geniCodeRValue (left, FALSE);
3252 right = geniCodeRValue (right, FALSE);
3253 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3256 return geniCodeAddressOf (left);
3258 case '|': /* bitwise or & xor */
3260 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3261 geniCodeRValue (right, FALSE),
3266 return geniCodeDivision (geniCodeRValue (left, FALSE),
3267 geniCodeRValue (right, FALSE));
3270 return geniCodeModulus (geniCodeRValue (left, FALSE),
3271 geniCodeRValue (right, FALSE));
3274 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3275 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3277 return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
3281 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3282 geniCodeRValue (right, FALSE));
3284 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3288 return geniCodeAdd (geniCodeRValue (left, FALSE),
3289 geniCodeRValue (right, FALSE));
3291 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3294 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3295 geniCodeRValue (right, FALSE));
3298 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3299 geniCodeRValue (right, FALSE));
3301 return geniCodeCast (operandType (left),
3302 geniCodeRValue (right, FALSE), FALSE);
3308 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3312 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3313 setOperandType (op, UCHARTYPE);
3324 return geniCodeLogic (geniCodeRValue (left, FALSE),
3325 geniCodeRValue (right, FALSE),
3328 return geniCodeConditional (tree);
3331 return operandFromLit (getSize (tree->right->ftype));
3335 sym_link *rtype = operandType (right);
3336 sym_link *ltype = operandType (left);
3337 if (IS_PTR (rtype) && IS_ITEMP (right)
3338 && right->isaddr && checkType (rtype->next, ltype) == 1)
3339 right = geniCodeRValue (right, TRUE);
3341 right = geniCodeRValue (right, FALSE);
3343 geniCodeAssign (left, right, 0);
3348 geniCodeAssign (left,
3349 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3351 geniCodeRValue (right, FALSE),FALSE), 0);
3355 geniCodeAssign (left,
3356 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3358 geniCodeRValue (right, FALSE)), 0);
3361 geniCodeAssign (left,
3362 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3364 geniCodeRValue (right, FALSE)), 0);
3367 sym_link *rtype = operandType (right);
3368 sym_link *ltype = operandType (left);
3369 if (IS_PTR (rtype) && IS_ITEMP (right)
3370 && right->isaddr && checkType (rtype->next, ltype) == 1)
3371 right = geniCodeRValue (right, TRUE);
3373 right = geniCodeRValue (right, FALSE);
3376 return geniCodeAssign (left,
3377 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3383 sym_link *rtype = operandType (right);
3384 sym_link *ltype = operandType (left);
3385 if (IS_PTR (rtype) && IS_ITEMP (right)
3386 && right->isaddr && checkType (rtype->next, ltype) == 1)
3388 right = geniCodeRValue (right, TRUE);
3392 right = geniCodeRValue (right, FALSE);
3395 geniCodeAssign (left,
3396 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3402 geniCodeAssign (left,
3403 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3405 geniCodeRValue (right, FALSE)), 0);
3408 geniCodeAssign (left,
3409 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3411 geniCodeRValue (right, FALSE)), 0);
3414 geniCodeAssign (left,
3415 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3417 geniCodeRValue (right, FALSE),
3419 operandType (left)), 0);
3422 geniCodeAssign (left,
3423 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3425 geniCodeRValue (right, FALSE),
3427 operandType (left)), 0);
3430 geniCodeAssign (left,
3431 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3433 geniCodeRValue (right, FALSE),
3435 operandType (left)), 0);
3437 return geniCodeRValue (right, FALSE);
3440 return geniCodeCall (ast2iCode (tree->left),
3443 geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
3444 return ast2iCode (tree->right);
3447 geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
3448 return ast2iCode (tree->right);
3451 geniCodeFunctionBody (tree);
3455 geniCodeReturn (right);
3463 geniCodeSwitch (tree);
3467 geniCodeInline (tree);
3474 /*-----------------------------------------------------------------*/
3475 /* reverseICChain - gets from the list and creates a linkedlist */
3476 /*-----------------------------------------------------------------*/
3483 while ((loop = getSet (&iCodeChain)))
3495 /*-----------------------------------------------------------------*/
3496 /* iCodeFromAst - given an ast will convert it to iCode */
3497 /*-----------------------------------------------------------------*/
3499 iCodeFromAst (ast * tree)
3501 returnLabel = newiTempLabel ("_return");
3502 entryLabel = newiTempLabel ("_entry");
3504 return reverseiCChain ();