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 // there is no need to multiply with 1
1915 if (getSize(ltype->next)!=1) {
1916 size = operandFromLit (getSize (ltype->next));
1917 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1919 resType = copyLinkChain (ltype);
1922 { /* make them the same size */
1923 resType = usualBinaryConversions (&left, &right);
1926 /* if they are both literals then we know */
1927 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1928 && left->isLiteral && right->isLiteral)
1929 return operandFromValue (valPlus (valFromType (letype),
1930 valFromType (retype)));
1932 ic = newiCode ('+', left, right);
1934 IC_RESULT (ic) = newiTempOperand (resType, 1);
1935 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1937 /* if left or right is a float then support
1939 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1944 return IC_RESULT (ic);
1948 /*-----------------------------------------------------------------*/
1949 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1950 /*-----------------------------------------------------------------*/
1952 aggrToPtr (sym_link * type, bool force)
1958 if (IS_PTR (type) && !force)
1961 etype = getSpec (type);
1965 /* if the output class is generic */
1966 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1967 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1969 /* if the variable was declared a constant */
1970 /* then the pointer points to a constant */
1971 if (IS_CONSTANT (etype))
1972 DCL_PTR_CONST (ptype) = 1;
1974 /* the variable was volatile then pointer to volatile */
1975 if (IS_VOLATILE (etype))
1976 DCL_PTR_VOLATILE (ptype) = 1;
1980 /*-----------------------------------------------------------------*/
1981 /* geniCodeArray2Ptr - array to pointer */
1982 /*-----------------------------------------------------------------*/
1984 geniCodeArray2Ptr (operand * op)
1986 sym_link *optype = operandType (op);
1987 sym_link *opetype = getSpec (optype);
1989 /* set the pointer depending on the storage class */
1990 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1991 DCL_PTR_CONST (optype) = port->mem.code_ro;
1994 /* if the variable was declared a constant */
1995 /* then the pointer points to a constant */
1996 if (IS_CONSTANT (opetype))
1997 DCL_PTR_CONST (optype) = 1;
1999 /* the variable was volatile then pointer to volatile */
2000 if (IS_VOLATILE (opetype))
2001 DCL_PTR_VOLATILE (optype) = 1;
2007 /*-----------------------------------------------------------------*/
2008 /* geniCodeArray - array access */
2009 /*-----------------------------------------------------------------*/
2011 geniCodeArray (operand * left, operand * right)
2014 sym_link *ltype = operandType (left);
2018 if (IS_PTR (ltype->next) && left->isaddr)
2020 left = geniCodeRValue (left, FALSE);
2022 return geniCodeDerefPtr (geniCodeAdd (left, right));
2025 right = geniCodeMultiply (right,
2026 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2028 /* we can check for limits here */
2029 if (isOperandLiteral (right) &&
2032 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2034 werror (E_ARRAY_BOUND);
2035 right = operandFromLit (0);
2038 ic = newiCode ('+', left, right);
2040 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2041 !IS_AGGREGATE (ltype->next) &&
2042 !IS_PTR (ltype->next))
2043 ? ltype : ltype->next), 0);
2045 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2047 return IC_RESULT (ic);
2050 /*-----------------------------------------------------------------*/
2051 /* geniCodeStruct - generates intermediate code for structres */
2052 /*-----------------------------------------------------------------*/
2054 geniCodeStruct (operand * left, operand * right, bool islval)
2057 sym_link *type = operandType (left);
2058 sym_link *etype = getSpec (type);
2060 symbol *element = getStructElement (SPEC_STRUCT (etype),
2061 right->operand.symOperand);
2063 /* add the offset */
2064 ic = newiCode ('+', left, operandFromLit (element->offset));
2066 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2068 /* preserve the storage & output class of the struct */
2069 /* as well as the volatile attribute */
2070 retype = getSpec (operandType (IC_RESULT (ic)));
2071 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2072 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2073 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2075 if (IS_PTR (element->type))
2076 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2078 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2082 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2085 /*-----------------------------------------------------------------*/
2086 /* geniCodePostInc - generate int code for Post increment */
2087 /*-----------------------------------------------------------------*/
2089 geniCodePostInc (operand * op)
2093 sym_link *optype = operandType (op);
2095 operand *rv = (IS_ITEMP (op) ?
2096 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2098 sym_link *rvtype = operandType (rv);
2101 /* if this is not an address we have trouble */
2104 werror (E_LVALUE_REQUIRED, "++");
2108 rOp = newiTempOperand (rvtype, 0);
2114 geniCodeAssign (rOp, rv, 0);
2116 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2117 if (IS_FLOAT (rvtype))
2118 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2120 ic = newiCode ('+', rv, operandFromLit (size));
2122 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2125 geniCodeAssign (op, result, 0);
2131 /*-----------------------------------------------------------------*/
2132 /* geniCodePreInc - generate code for preIncrement */
2133 /*-----------------------------------------------------------------*/
2135 geniCodePreInc (operand * op)
2138 sym_link *optype = operandType (op);
2139 operand *rop = (IS_ITEMP (op) ?
2140 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2142 sym_link *roptype = operandType (rop);
2148 werror (E_LVALUE_REQUIRED, "++");
2153 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2154 if (IS_FLOAT (roptype))
2155 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2157 ic = newiCode ('+', rop, operandFromLit (size));
2158 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2162 return geniCodeAssign (op, result, 0);
2165 /*-----------------------------------------------------------------*/
2166 /* geniCodePostDec - generates code for Post decrement */
2167 /*-----------------------------------------------------------------*/
2169 geniCodePostDec (operand * op)
2173 sym_link *optype = operandType (op);
2175 operand *rv = (IS_ITEMP (op) ?
2176 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2178 sym_link *rvtype = operandType (rv);
2181 /* if this is not an address we have trouble */
2184 werror (E_LVALUE_REQUIRED, "++");
2188 rOp = newiTempOperand (rvtype, 0);
2194 geniCodeAssign (rOp, rv, 0);
2196 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2197 if (IS_FLOAT (rvtype))
2198 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2200 ic = newiCode ('-', rv, operandFromLit (size));
2202 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2205 geniCodeAssign (op, result, 0);
2211 /*-----------------------------------------------------------------*/
2212 /* geniCodePreDec - generate code for pre decrement */
2213 /*-----------------------------------------------------------------*/
2215 geniCodePreDec (operand * op)
2218 sym_link *optype = operandType (op);
2219 operand *rop = (IS_ITEMP (op) ?
2220 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2222 sym_link *roptype = operandType (rop);
2228 werror (E_LVALUE_REQUIRED, "++");
2233 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2234 if (IS_FLOAT (roptype))
2235 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2237 ic = newiCode ('-', rop, operandFromLit (size));
2238 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2242 return geniCodeAssign (op, result, 0);
2246 /*-----------------------------------------------------------------*/
2247 /* geniCodeBitwise - gen int code for bitWise operators */
2248 /*-----------------------------------------------------------------*/
2250 geniCodeBitwise (operand * left, operand * right,
2251 int oper, sym_link * resType)
2255 left = geniCodeCast (resType, left, TRUE);
2256 right = geniCodeCast (resType, right, TRUE);
2258 ic = newiCode (oper, left, right);
2259 IC_RESULT (ic) = newiTempOperand (resType, 0);
2262 return IC_RESULT (ic);
2265 /*-----------------------------------------------------------------*/
2266 /* geniCodeAddressOf - gens icode for '&' address of operator */
2267 /*-----------------------------------------------------------------*/
2269 geniCodeAddressOf (operand * op)
2273 sym_link *optype = operandType (op);
2274 sym_link *opetype = getSpec (optype);
2276 /* lvalue check already done in decorateType */
2277 /* this must be a lvalue */
2278 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2279 /* werror (E_LVALUE_REQUIRED,"&"); */
2284 p->class = DECLARATOR;
2286 /* set the pointer depending on the storage class */
2287 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2288 DCL_PTR_CONST (p) = port->mem.code_ro;
2290 /* make sure we preserve the const & volatile */
2291 if (IS_CONSTANT (opetype))
2292 DCL_PTR_CONST (p) = 1;
2294 if (IS_VOLATILE (opetype))
2295 DCL_PTR_VOLATILE (p) = 1;
2297 p->next = copyLinkChain (optype);
2299 /* if already a temp */
2302 setOperandType (op, p);
2307 /* other wise make this of the type coming in */
2308 ic = newiCode (ADDRESS_OF, op, NULL);
2309 IC_RESULT (ic) = newiTempOperand (p, 1);
2310 IC_RESULT (ic)->isaddr = 0;
2312 return IC_RESULT (ic);
2314 /*-----------------------------------------------------------------*/
2315 /* setOClass - sets the output class depending on the pointer type */
2316 /*-----------------------------------------------------------------*/
2318 setOClass (sym_link * ptr, sym_link * spec)
2320 switch (DCL_TYPE (ptr))
2323 SPEC_OCLS (spec) = data;
2327 SPEC_OCLS (spec) = generic;
2331 SPEC_OCLS (spec) = xdata;
2335 SPEC_OCLS (spec) = code;
2339 SPEC_OCLS (spec) = idata;
2343 SPEC_OCLS (spec) = xstack;
2347 SPEC_OCLS (spec) = eeprom;
2356 /*-----------------------------------------------------------------*/
2357 /* geniCodeDerefPtr - dereference pointer with '*' */
2358 /*-----------------------------------------------------------------*/
2360 geniCodeDerefPtr (operand * op)
2362 sym_link *rtype, *retype;
2363 sym_link *optype = operandType (op);
2365 /* if this is a pointer then generate the rvalue */
2366 if (IS_PTR (optype))
2368 if (IS_TRUE_SYMOP (op))
2371 op = geniCodeRValue (op, TRUE);
2374 op = geniCodeRValue (op, TRUE);
2377 /* now get rid of the pointer part */
2378 if (lvaluereq && IS_ITEMP (op))
2380 retype = getSpec (rtype = copyLinkChain (optype));
2384 retype = getSpec (rtype = copyLinkChain (optype->next));
2387 /* if this is a pointer then outputclass needs 2b updated */
2388 if (IS_PTR (optype))
2389 setOClass (optype, retype);
2391 op->isGptr = IS_GENPTR (optype);
2393 /* if the pointer was declared as a constant */
2394 /* then we cannot allow assignment to the derefed */
2395 if (IS_PTR_CONST (optype))
2396 SPEC_CONST (retype) = 1;
2398 op->isaddr = (IS_PTR (rtype) ||
2399 IS_STRUCT (rtype) ||
2405 op = geniCodeRValue (op, TRUE);
2407 setOperandType (op, rtype);
2412 /*-----------------------------------------------------------------*/
2413 /* geniCodeUnaryMinus - does a unary minus of the operand */
2414 /*-----------------------------------------------------------------*/
2416 geniCodeUnaryMinus (operand * op)
2419 sym_link *optype = operandType (op);
2421 if (IS_LITERAL (optype))
2422 return operandFromLit (-floatFromVal (op->operand.valOperand));
2424 ic = newiCode (UNARYMINUS, op, NULL);
2425 IC_RESULT (ic) = newiTempOperand (optype, 0);
2427 return IC_RESULT (ic);
2430 /*-----------------------------------------------------------------*/
2431 /* geniCodeLeftShift - gen i code for left shift */
2432 /*-----------------------------------------------------------------*/
2434 geniCodeLeftShift (operand * left, operand * right)
2439 /* Note that we don't use the usual binary conversions for the
2440 * shift operations, in accordance with our ANSI friends.
2442 if (options.ANSIint)
2444 right = usualUnaryConversions (right);
2445 left = usualUnaryConversions (left);
2448 ic = newiCode (LEFT_OP, left, right);
2449 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2451 return IC_RESULT (ic);
2454 /*-----------------------------------------------------------------*/
2455 /* geniCodeRightShift - gen i code for right shift */
2456 /*-----------------------------------------------------------------*/
2458 geniCodeRightShift (operand * left, operand * right)
2463 /* Note that we don't use the usual binary conversions for the
2464 * shift operations, in accordance with our ANSI friends.
2466 if (options.ANSIint)
2468 right = usualUnaryConversions (right);
2469 left = usualUnaryConversions (left);
2472 ic = newiCode (RIGHT_OP, left, right);
2473 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2475 return IC_RESULT (ic);
2478 #if defined(__BORLANDC__) || defined(_MSC_VER)
2479 #define LONG_LONG __int64
2481 #define LONG_LONG long long
2484 /*-----------------------------------------------------------------*/
2485 /* geniCodeLogic- logic code */
2486 /*-----------------------------------------------------------------*/
2488 geniCodeLogic (operand * left, operand * right, int op)
2492 sym_link *rtype = operandType (right);
2493 sym_link *ltype = operandType (left);
2495 /* left is integral type and right is literal then
2496 check if the literal value is within bounds */
2497 if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
2499 int nbits = bitsForType (ltype);
2500 long v = operandLitValue (right);
2502 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2503 werror (W_CONST_RANGE, " compare operation ");
2506 ctype = usualBinaryConversions (&left, &right);
2508 ic = newiCode (op, left, right);
2509 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2511 /* if comparing float
2512 and not a '==' || '!=' || '&&' || '||' (these
2514 if (IS_FLOAT(ctype) &&
2522 return IC_RESULT (ic);
2525 /*-----------------------------------------------------------------*/
2526 /* geniCodeUnary - for a a generic unary operation */
2527 /*-----------------------------------------------------------------*/
2529 geniCodeUnary (operand * op, int oper)
2531 iCode *ic = newiCode (oper, op, NULL);
2533 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2535 return IC_RESULT (ic);
2538 /*-----------------------------------------------------------------*/
2539 /* geniCodeConditional - geniCode for '?' ':' operation */
2540 /*-----------------------------------------------------------------*/
2542 geniCodeConditional (ast * tree)
2545 symbol *falseLabel = newiTempLabel (NULL);
2546 symbol *exitLabel = newiTempLabel (NULL);
2547 operand *cond = ast2iCode (tree->left);
2548 operand *true, *false, *result;
2550 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2554 true = ast2iCode (tree->right->left);
2556 /* move the value to a new Operand */
2557 result = newiTempOperand (operandType (true), 0);
2558 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2560 /* generate an unconditional goto */
2561 geniCodeGoto (exitLabel);
2563 /* now for the right side */
2564 geniCodeLabel (falseLabel);
2566 false = ast2iCode (tree->right->right);
2567 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2569 /* create the exit label */
2570 geniCodeLabel (exitLabel);
2575 /*-----------------------------------------------------------------*/
2576 /* geniCodeAssign - generate code for assignment */
2577 /*-----------------------------------------------------------------*/
2579 geniCodeAssign (operand * left, operand * right, int nosupdate)
2582 sym_link *ltype = operandType (left);
2583 sym_link *rtype = operandType (right);
2585 if (!left->isaddr && !IS_ITEMP (left))
2587 werror (E_LVALUE_REQUIRED, "assignment");
2591 /* left is integral type and right is literal then
2592 check if the literal value is within bounds */
2593 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2595 int nbits = bitsForType (ltype);
2596 long v = operandLitValue (right);
2598 if (v > ((LONG_LONG) 1 << nbits) && v > 0)
2599 werror (W_CONST_RANGE, " = operation");
2602 /* if the left & right type don't exactly match */
2603 /* if pointer set then make sure the check is
2604 done with the type & not the pointer */
2605 /* then cast rights type to left */
2607 /* first check the type for pointer assignement */
2608 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2609 checkType (ltype, rtype) < 0)
2611 if (checkType (ltype->next, rtype) < 0)
2612 right = geniCodeCast (ltype->next, right, TRUE);
2614 else if (checkType (ltype, rtype) < 0)
2615 right = geniCodeCast (ltype, right, TRUE);
2617 /* if left is a true symbol & ! volatile
2618 create an assignment to temporary for
2619 the right & then assign this temporary
2620 to the symbol this is SSA . isn't it simple
2621 and folks have published mountains of paper on it */
2622 if (IS_TRUE_SYMOP (left) &&
2623 !isOperandVolatile (left, FALSE) &&
2624 isOperandGlobal (left))
2628 if (IS_TRUE_SYMOP (right))
2629 sym = OP_SYMBOL (right);
2630 ic = newiCode ('=', NULL, right);
2631 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2632 SPIL_LOC (right) = sym;
2636 ic = newiCode ('=', NULL, right);
2637 IC_RESULT (ic) = left;
2640 /* if left isgptr flag is set then support
2641 routine will be required */
2645 ic->nosupdate = nosupdate;
2649 /*-----------------------------------------------------------------*/
2650 /* geniCodeSEParms - generate code for side effecting fcalls */
2651 /*-----------------------------------------------------------------*/
2653 geniCodeSEParms (ast * parms)
2658 if (parms->type == EX_OP && parms->opval.op == PARAM)
2660 geniCodeSEParms (parms->left);
2661 geniCodeSEParms (parms->right);
2665 /* hack don't like this but too lazy to think of
2667 if (IS_ADDRESS_OF_OP (parms))
2668 parms->left->lvalue = 1;
2670 if (IS_CAST_OP (parms) &&
2671 IS_PTR (parms->ftype) &&
2672 IS_ADDRESS_OF_OP (parms->right))
2673 parms->right->left->lvalue = 1;
2675 parms->opval.oprnd =
2676 geniCodeRValue (ast2iCode (parms), FALSE);
2678 parms->type = EX_OPERAND;
2681 /*-----------------------------------------------------------------*/
2682 /* geniCodeParms - generates parameters */
2683 /*-----------------------------------------------------------------*/
2685 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
2693 /* if this is a param node then do the left & right */
2694 if (parms->type == EX_OP && parms->opval.op == PARAM)
2696 geniCodeParms (parms->left, stack, fetype, func);
2697 geniCodeParms (parms->right, stack, fetype, func);
2701 /* get the parameter value */
2702 if (parms->type == EX_OPERAND)
2703 pval = parms->opval.oprnd;
2706 /* maybe this else should go away ?? */
2707 /* hack don't like this but too lazy to think of
2709 if (IS_ADDRESS_OF_OP (parms))
2710 parms->left->lvalue = 1;
2712 if (IS_CAST_OP (parms) &&
2713 IS_PTR (parms->ftype) &&
2714 IS_ADDRESS_OF_OP (parms->right))
2715 parms->right->left->lvalue = 1;
2717 pval = geniCodeRValue (ast2iCode (parms), FALSE);
2720 /* if register parm then make it a send */
2721 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2722 IS_REGPARM (parms->etype)) && !func->hasVargs)
2724 ic = newiCode (SEND, pval, NULL);
2729 /* now decide whether to push or assign */
2730 if (!(options.stackAuto || IS_RENT (fetype)))
2734 operand *top = operandFromSymbol (parms->argSym);
2735 geniCodeAssign (top, pval, 1);
2739 sym_link *p = operandType (pval);
2741 ic = newiCode (IPUSH, pval, NULL);
2743 /* update the stack adjustment */
2744 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2751 /*-----------------------------------------------------------------*/
2752 /* geniCodeCall - generates temp code for calling */
2753 /*-----------------------------------------------------------------*/
2755 geniCodeCall (operand * left, ast * parms)
2759 sym_link *type, *etype;
2762 /* take care of parameters with side-effecting
2763 function calls in them, this is required to take care
2764 of overlaying function parameters */
2765 geniCodeSEParms (parms);
2767 /* first the parameters */
2768 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
2770 /* now call : if symbol then pcall */
2771 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2772 ic = newiCode (PCALL, left, NULL);
2774 ic = newiCode (CALL, left, NULL);
2776 IC_ARGS (ic) = left->operand.symOperand->args;
2777 type = copyLinkChain (operandType (left)->next);
2778 etype = getSpec (type);
2779 SPEC_EXTR (etype) = 0;
2780 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2784 /* stack adjustment after call */
2785 ic->parmBytes = stack;
2790 /*-----------------------------------------------------------------*/
2791 /* geniCodeReceive - generate intermediate code for "receive" */
2792 /*-----------------------------------------------------------------*/
2794 geniCodeReceive (value * args)
2796 /* for all arguments that are passed in registers */
2800 if (IS_REGPARM (args->etype))
2802 operand *opr = operandFromValue (args);
2804 symbol *sym = OP_SYMBOL (opr);
2807 /* we will use it after all optimizations
2808 and before liveRange calculation */
2809 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2812 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2813 options.stackAuto == 0 &&
2819 opl = newiTempOperand (args->type, 0);
2821 sym->reqv->key = sym->key;
2822 OP_SYMBOL (sym->reqv)->key = sym->key;
2823 OP_SYMBOL (sym->reqv)->isreqv = 1;
2824 OP_SYMBOL (sym->reqv)->islocal = 0;
2825 SPIL_LOC (sym->reqv) = sym;
2829 ic = newiCode (RECEIVE, NULL, NULL);
2830 currFunc->recvSize = getSize (sym->etype);
2831 IC_RESULT (ic) = opr;
2839 /*-----------------------------------------------------------------*/
2840 /* geniCodeFunctionBody - create the function body */
2841 /*-----------------------------------------------------------------*/
2843 geniCodeFunctionBody (ast * tree)
2850 /* reset the auto generation */
2856 func = ast2iCode (tree->left);
2857 fetype = getSpec (operandType (func));
2859 savelineno = lineno;
2860 lineno = OP_SYMBOL (func)->lineDef;
2861 /* create an entry label */
2862 geniCodeLabel (entryLabel);
2863 lineno = savelineno;
2865 /* create a proc icode */
2866 ic = newiCode (FUNCTION, func, NULL);
2867 /* if the function has parmas then */
2868 /* save the parameters information */
2869 ic->argLabel.args = tree->values.args;
2870 ic->lineno = OP_SYMBOL (func)->lineDef;
2874 /* for all parameters that are passed
2875 on registers add a "receive" */
2876 geniCodeReceive (tree->values.args);
2878 /* generate code for the body */
2879 ast2iCode (tree->right);
2881 /* create a label for return */
2882 geniCodeLabel (returnLabel);
2884 /* now generate the end proc */
2885 ic = newiCode (ENDFUNCTION, func, NULL);
2890 /*-----------------------------------------------------------------*/
2891 /* geniCodeReturn - gen icode for 'return' statement */
2892 /*-----------------------------------------------------------------*/
2894 geniCodeReturn (operand * op)
2898 /* if the operand is present force an rvalue */
2900 op = geniCodeRValue (op, FALSE);
2902 ic = newiCode (RETURN, op, NULL);
2906 /*-----------------------------------------------------------------*/
2907 /* geniCodeIfx - generates code for extended if statement */
2908 /*-----------------------------------------------------------------*/
2910 geniCodeIfx (ast * tree)
2913 operand *condition = ast2iCode (tree->left);
2916 /* if condition is null then exit */
2920 condition = geniCodeRValue (condition, FALSE);
2922 cetype = getSpec (operandType (condition));
2923 /* if the condition is a literal */
2924 if (IS_LITERAL (cetype))
2926 if (floatFromVal (condition->operand.valOperand))
2928 if (tree->trueLabel)
2929 geniCodeGoto (tree->trueLabel);
2935 if (tree->falseLabel)
2936 geniCodeGoto (tree->falseLabel);
2943 if (tree->trueLabel)
2945 ic = newiCodeCondition (condition,
2950 if (tree->falseLabel)
2951 geniCodeGoto (tree->falseLabel);
2955 ic = newiCodeCondition (condition,
2962 ast2iCode (tree->right);
2965 /*-----------------------------------------------------------------*/
2966 /* geniCodeJumpTable - tries to create a jump table for switch */
2967 /*-----------------------------------------------------------------*/
2969 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2971 int min = 0, max = 0, t, cnt = 0;
2978 if (!tree || !caseVals)
2981 /* the criteria for creating a jump table is */
2982 /* all integer numbers between the maximum & minimum must */
2983 /* be present , the maximum value should not exceed 255 */
2984 min = max = (int) floatFromVal (vch = caseVals);
2985 sprintf (buffer, "_case_%d_%d",
2986 tree->values.switchVals.swNum,
2988 addSet (&labels, newiTempLabel (buffer));
2990 /* if there is only one case value then no need */
2991 if (!(vch = vch->next))
2996 if (((t = (int) floatFromVal (vch)) - max) != 1)
2998 sprintf (buffer, "_case_%d_%d",
2999 tree->values.switchVals.swNum,
3001 addSet (&labels, newiTempLabel (buffer));
3007 /* if the number of case statements <= 2 then */
3008 /* it is not economical to create the jump table */
3009 /* since two compares are needed for boundary conditions */
3010 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3013 if (tree->values.switchVals.swDefault)
3014 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3016 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3018 falseLabel = newiTempLabel (buffer);
3020 /* so we can create a jumptable */
3021 /* first we rule out the boundary conditions */
3022 /* if only optimization says so */
3023 if (!optimize.noJTabBoundary)
3025 sym_link *cetype = getSpec (operandType (cond));
3026 /* no need to check the lower bound if
3027 the condition is unsigned & minimum value is zero */
3028 if (!(min == 0 && SPEC_USIGN (cetype)))
3030 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3031 ic = newiCodeCondition (boundary, falseLabel, NULL);
3035 /* now for upper bounds */
3036 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3037 ic = newiCodeCondition (boundary, falseLabel, NULL);
3041 /* if the min is not zero then we no make it zero */
3044 cond = geniCodeSubtract (cond, operandFromLit (min));
3045 setOperandType (cond, UCHARTYPE);
3048 /* now create the jumptable */
3049 ic = newiCode (JUMPTABLE, NULL, NULL);
3050 IC_JTCOND (ic) = cond;
3051 IC_JTLABELS (ic) = labels;
3056 /*-----------------------------------------------------------------*/
3057 /* geniCodeSwitch - changes a switch to a if statement */
3058 /*-----------------------------------------------------------------*/
3060 geniCodeSwitch (ast * tree)
3063 operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
3064 value *caseVals = tree->values.switchVals.swVals;
3065 symbol *trueLabel, *falseLabel;
3067 /* if we can make this a jump table */
3068 if (geniCodeJumpTable (cond, caseVals, tree))
3069 goto jumpTable; /* no need for the comparison */
3071 /* for the cases defined do */
3075 operand *compare = geniCodeLogic (cond,
3076 operandFromValue (caseVals),
3079 sprintf (buffer, "_case_%d_%d",
3080 tree->values.switchVals.swNum,
3081 (int) floatFromVal (caseVals));
3082 trueLabel = newiTempLabel (buffer);
3084 ic = newiCodeCondition (compare, trueLabel, NULL);
3086 caseVals = caseVals->next;
3091 /* if default is present then goto break else break */
3092 if (tree->values.switchVals.swDefault)
3093 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3095 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3097 falseLabel = newiTempLabel (buffer);
3098 geniCodeGoto (falseLabel);
3101 ast2iCode (tree->right);
3104 /*-----------------------------------------------------------------*/
3105 /* geniCodeInline - intermediate code for inline assembler */
3106 /*-----------------------------------------------------------------*/
3108 geniCodeInline (ast * tree)
3112 ic = newiCode (INLINEASM, NULL, NULL);
3113 IC_INLINE (ic) = tree->values.inlineasm;
3117 /*-----------------------------------------------------------------*/
3118 /* ast2iCode - creates an icodeList from an ast */
3119 /*-----------------------------------------------------------------*/
3121 ast2iCode (ast * tree)
3123 operand *left = NULL;
3124 operand *right = NULL;
3129 /* set the global variables for filename & line number */
3131 filename = tree->filename;
3133 lineno = tree->lineno;
3135 block = tree->block;
3137 scopeLevel = tree->level;
3139 if (tree->type == EX_VALUE)
3140 return operandFromValue (tree->opval.val);
3142 if (tree->type == EX_LINK)
3143 return operandFromLink (tree->opval.lnk);
3145 /* if we find a nullop */
3146 if (tree->type == EX_OP &&
3147 (tree->opval.op == NULLOP ||
3148 tree->opval.op == BLOCK))
3150 ast2iCode (tree->left);
3151 ast2iCode (tree->right);
3155 /* special cases for not evaluating */
3156 if (tree->opval.op != ':' &&
3157 tree->opval.op != '?' &&
3158 tree->opval.op != CALL &&
3159 tree->opval.op != IFX &&
3160 tree->opval.op != LABEL &&
3161 tree->opval.op != GOTO &&
3162 tree->opval.op != SWITCH &&
3163 tree->opval.op != FUNCTION &&
3164 tree->opval.op != INLINEASM)
3167 if (IS_ASSIGN_OP (tree->opval.op) ||
3168 IS_DEREF_OP (tree) ||
3169 (tree->opval.op == '&' && !tree->right) ||
3170 tree->opval.op == PTR_OP)
3173 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3174 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3176 int olvr = lvaluereq;
3178 left = operandFromAst (tree->left);
3179 lvaluereq = olvr - 1;
3183 left = operandFromAst (tree->left);
3186 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3187 left = geniCodeRValue (left, TRUE);
3191 left = operandFromAst (tree->left);
3193 if (tree->opval.op == INC_OP ||
3194 tree->opval.op == DEC_OP)
3197 right = operandFromAst (tree->right);
3202 right = operandFromAst (tree->right);
3206 /* now depending on the type of operand */
3207 /* this will be a biggy */
3208 switch (tree->opval.op)
3211 case '[': /* array operation */
3213 sym_link *ltype = operandType (left);
3214 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3215 right = geniCodeRValue (right, TRUE);
3218 return geniCodeArray (left, right);
3220 case '.': /* structure dereference */
3221 if (IS_PTR (operandType (left)))
3222 left = geniCodeRValue (left, TRUE);
3224 left = geniCodeRValue (left, FALSE);
3226 return geniCodeStruct (left, right, tree->lvalue);
3228 case PTR_OP: /* structure pointer dereference */
3231 pType = operandType (left);
3232 left = geniCodeRValue (left, TRUE);
3234 setOClass (pType, getSpec (operandType (left)));
3237 return geniCodeStruct (left, right, tree->lvalue);
3239 case INC_OP: /* increment operator */
3241 return geniCodePostInc (left);
3243 return geniCodePreInc (right);
3245 case DEC_OP: /* decrement operator */
3247 return geniCodePostDec (left);
3249 return geniCodePreDec (right);
3251 case '&': /* bitwise and or address of operator */
3253 { /* this is a bitwise operator */
3254 left = geniCodeRValue (left, FALSE);
3255 right = geniCodeRValue (right, FALSE);
3256 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3259 return geniCodeAddressOf (left);
3261 case '|': /* bitwise or & xor */
3263 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3264 geniCodeRValue (right, FALSE),
3269 return geniCodeDivision (geniCodeRValue (left, FALSE),
3270 geniCodeRValue (right, FALSE));
3273 return geniCodeModulus (geniCodeRValue (left, FALSE),
3274 geniCodeRValue (right, FALSE));
3277 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3278 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3280 return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
3284 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3285 geniCodeRValue (right, FALSE));
3287 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3291 return geniCodeAdd (geniCodeRValue (left, FALSE),
3292 geniCodeRValue (right, FALSE));
3294 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3297 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3298 geniCodeRValue (right, FALSE));
3301 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3302 geniCodeRValue (right, FALSE));
3304 return geniCodeCast (operandType (left),
3305 geniCodeRValue (right, FALSE), FALSE);
3311 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3315 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3316 setOperandType (op, UCHARTYPE);
3327 return geniCodeLogic (geniCodeRValue (left, FALSE),
3328 geniCodeRValue (right, FALSE),
3331 return geniCodeConditional (tree);
3334 return operandFromLit (getSize (tree->right->ftype));
3338 sym_link *rtype = operandType (right);
3339 sym_link *ltype = operandType (left);
3340 if (IS_PTR (rtype) && IS_ITEMP (right)
3341 && right->isaddr && checkType (rtype->next, ltype) == 1)
3342 right = geniCodeRValue (right, TRUE);
3344 right = geniCodeRValue (right, FALSE);
3346 geniCodeAssign (left, right, 0);
3351 geniCodeAssign (left,
3352 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3354 geniCodeRValue (right, FALSE),FALSE), 0);
3358 geniCodeAssign (left,
3359 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3361 geniCodeRValue (right, FALSE)), 0);
3364 geniCodeAssign (left,
3365 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3367 geniCodeRValue (right, FALSE)), 0);
3370 sym_link *rtype = operandType (right);
3371 sym_link *ltype = operandType (left);
3372 if (IS_PTR (rtype) && IS_ITEMP (right)
3373 && right->isaddr && checkType (rtype->next, ltype) == 1)
3374 right = geniCodeRValue (right, TRUE);
3376 right = geniCodeRValue (right, FALSE);
3379 return geniCodeAssign (left,
3380 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3386 sym_link *rtype = operandType (right);
3387 sym_link *ltype = operandType (left);
3388 if (IS_PTR (rtype) && IS_ITEMP (right)
3389 && right->isaddr && checkType (rtype->next, ltype) == 1)
3391 right = geniCodeRValue (right, TRUE);
3395 right = geniCodeRValue (right, FALSE);
3398 geniCodeAssign (left,
3399 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3405 geniCodeAssign (left,
3406 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3408 geniCodeRValue (right, FALSE)), 0);
3411 geniCodeAssign (left,
3412 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3414 geniCodeRValue (right, FALSE)), 0);
3417 geniCodeAssign (left,
3418 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3420 geniCodeRValue (right, FALSE),
3422 operandType (left)), 0);
3425 geniCodeAssign (left,
3426 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3428 geniCodeRValue (right, FALSE),
3430 operandType (left)), 0);
3433 geniCodeAssign (left,
3434 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3436 geniCodeRValue (right, FALSE),
3438 operandType (left)), 0);
3440 return geniCodeRValue (right, FALSE);
3443 return geniCodeCall (ast2iCode (tree->left),
3446 geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
3447 return ast2iCode (tree->right);
3450 geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
3451 return ast2iCode (tree->right);
3454 geniCodeFunctionBody (tree);
3458 geniCodeReturn (right);
3466 geniCodeSwitch (tree);
3470 geniCodeInline (tree);
3477 /*-----------------------------------------------------------------*/
3478 /* reverseICChain - gets from the list and creates a linkedlist */
3479 /*-----------------------------------------------------------------*/
3486 while ((loop = getSet (&iCodeChain)))
3498 /*-----------------------------------------------------------------*/
3499 /* iCodeFromAst - given an ast will convert it to iCode */
3500 /*-----------------------------------------------------------------*/
3502 iCodeFromAst (ast * tree)
3504 returnLabel = newiTempLabel ("_return");
3505 entryLabel = newiTempLabel ("_entry");
3507 return reverseiCChain ();