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;
41 symbol *returnLabel; /* function return label */
42 symbol *entryLabel; /* function entry label */
44 #if defined(__BORLANDC__) || defined(_MSC_VER)
45 #define LONG_LONG __int64
47 #define LONG_LONG long long
50 /*-----------------------------------------------------------------*/
51 /* forward definition of some functions */
52 operand *geniCodeDivision (operand *, operand *);
53 operand *geniCodeAssign (operand *, operand *, int);
54 operand *geniCodeArray (operand *, operand *,int);
55 operand *geniCodeArray2Ptr (operand *);
56 operand *geniCodeRValue (operand *, bool);
57 operand *geniCodeDerefPtr (operand *,int);
58 int isLvaluereq(int lvl);
60 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
61 /* forward definition of ic print functions */
62 PRINTFUNC (picGetValueAtAddr);
63 PRINTFUNC (picSetValueAtAddr);
64 PRINTFUNC (picAddrOf);
65 PRINTFUNC (picGeneric);
66 PRINTFUNC (picGenericOne);
68 PRINTFUNC (picAssign);
72 PRINTFUNC (picJumpTable);
73 PRINTFUNC (picInline);
74 PRINTFUNC (picReceive);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
123 /*-----------------------------------------------------------------*/
124 /* checkConstantRange: check a constant against the type */
125 /*-----------------------------------------------------------------*/
127 /* pedantic=0: allmost anything is allowed as long as the absolute
128 value is within the bit range of the type, and -1 is treated as
129 0xf..f for unsigned types (e.g. in assign)
130 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
131 pedantic>1: "char c=200" is not allowed (evaluates to -56)
134 void checkConstantRange(sym_link *ltype, double v, char *msg, int pedantic) {
135 LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype);
136 char message[132]="";
141 // this could be a good idea
142 if (options.pedantic)
146 if (SPEC_NOUN(ltype)==FLOAT) {
153 // if not pedantic: -1 equals to 0xf..f
154 if (SPEC_USIGN(ltype) && (!pedantic ? v!=-1 : 1)) {
160 // if very pedantic: "char c=200" is not allowed
161 if (pedantic>1 && !SPEC_USIGN(ltype)) {
162 max = max/2 + negative;
170 sprintf (message, "for %s %s in %s",
171 SPEC_USIGN(ltype) ? "unsigned" : "signed",
172 nounName(ltype), msg);
173 werror (W_CONST_RANGE, message);
180 /*-----------------------------------------------------------------*/
181 /* operandName - returns the name of the operand */
182 /*-----------------------------------------------------------------*/
184 printOperand (operand * op, FILE * file)
201 opetype = getSpec (operandType (op));
202 if (SPEC_NOUN (opetype) == V_FLOAT)
203 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
205 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
206 printTypeChain (operandType (op), file);
213 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
214 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
216 OP_LIVEFROM (op), OP_LIVETO (op),
217 OP_SYMBOL (op)->stack,
218 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
222 printTypeChain (operandType (op), file);
223 if (SPIL_LOC (op) && IS_ITEMP (op))
224 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
229 /* if assigned to registers */
230 if (OP_SYMBOL (op)->nRegs)
232 if (OP_SYMBOL (op)->isspilt)
234 if (!OP_SYMBOL (op)->remat)
235 if (OP_SYMBOL (op)->usl.spillLoc)
236 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
237 OP_SYMBOL (op)->usl.spillLoc->rname :
238 OP_SYMBOL (op)->usl.spillLoc->name));
240 fprintf (file, "[err]");
242 fprintf (file, "[remat]");
248 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
249 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
254 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
255 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
256 /* if assigned to registers */
257 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
261 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
262 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
263 OP_SYMBOL (op)->regs[i]->name :
272 printTypeChain (op->operand.typeOperand, file);
278 fprintf (file, "\n");
283 /*-----------------------------------------------------------------*/
284 /* print functions */
285 /*-----------------------------------------------------------------*/
286 PRINTFUNC (picGetValueAtAddr)
289 printOperand (IC_RESULT (ic), of);
292 printOperand (IC_LEFT (ic), of);
298 PRINTFUNC (picSetValueAtAddr)
302 printOperand (IC_LEFT (ic), of);
303 fprintf (of, "] = ");
304 printOperand (IC_RIGHT (ic), of);
308 PRINTFUNC (picAddrOf)
311 printOperand (IC_RESULT (ic), of);
312 if (IS_ITEMP (IC_LEFT (ic)))
315 fprintf (of, " = &[");
316 printOperand (IC_LEFT (ic), of);
319 if (IS_ITEMP (IC_LEFT (ic)))
320 fprintf (of, " offsetAdd ");
323 printOperand (IC_RIGHT (ic), of);
325 if (IS_ITEMP (IC_LEFT (ic)))
331 PRINTFUNC (picJumpTable)
336 fprintf (of, "%s\t", s);
337 printOperand (IC_JTCOND (ic), of);
339 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
340 sym = setNextItem (IC_JTLABELS (ic)))
341 fprintf (of, "\t\t\t%s\n", sym->name);
344 PRINTFUNC (picGeneric)
347 printOperand (IC_RESULT (ic), of);
349 printOperand (IC_LEFT (ic), of);
350 fprintf (of, " %s ", s);
351 printOperand (IC_RIGHT (ic), of);
355 PRINTFUNC (picGenericOne)
360 printOperand (IC_RESULT (ic), of);
366 fprintf (of, "%s ", s);
367 printOperand (IC_LEFT (ic), of);
370 if (!IC_RESULT (ic) && !IC_LEFT (ic))
379 printOperand (IC_RESULT (ic), of);
381 printOperand (IC_LEFT (ic), of);
382 printOperand (IC_RIGHT (ic), of);
387 PRINTFUNC (picAssign)
391 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
394 printOperand (IC_RESULT (ic), of);
396 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
399 fprintf (of, " %s ", s);
400 printOperand (IC_RIGHT (ic), of);
407 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
413 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
420 printOperand (IC_COND (ic), of);
423 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
426 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
428 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
432 PRINTFUNC (picInline)
434 fprintf (of, "%s", IC_INLINE (ic));
437 PRINTFUNC (picReceive)
439 printOperand (IC_RESULT (ic), of);
440 fprintf (of, " = %s ", s);
441 printOperand (IC_LEFT (ic), of);
445 /*-----------------------------------------------------------------*/
446 /* piCode - prints one iCode */
447 /*-----------------------------------------------------------------*/
449 piCode (void *item, FILE * of)
457 icTab = getTableEntry (ic->op);
458 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
459 ic->filename, ic->lineno,
460 ic->seq, ic->key, ic->depth, ic->supportRtn);
461 icTab->iCodePrint (of, ic, icTab->printName);
467 printiCChain(ic,stdout);
469 /*-----------------------------------------------------------------*/
470 /* printiCChain - prints intermediate code for humans */
471 /*-----------------------------------------------------------------*/
473 printiCChain (iCode * icChain, FILE * of)
480 for (loop = icChain; loop; loop = loop->next)
482 if ((icTab = getTableEntry (loop->op)))
484 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
485 loop->filename, loop->lineno,
486 loop->seq, loop->key, loop->depth, loop->supportRtn);
488 icTab->iCodePrint (of, loop, icTab->printName);
494 /*-----------------------------------------------------------------*/
495 /* newOperand - allocate, init & return a new iCode */
496 /*-----------------------------------------------------------------*/
502 op = Safe_calloc (1, sizeof (operand));
508 /*-----------------------------------------------------------------*/
509 /* newiCode - create and return a new iCode entry initialised */
510 /*-----------------------------------------------------------------*/
512 newiCode (int op, operand * left, operand * right)
516 ic = Safe_calloc (1, sizeof (iCode));
519 ic->filename = filename;
521 ic->level = scopeLevel;
523 ic->key = iCodeKey++;
525 IC_RIGHT (ic) = right;
530 /*-----------------------------------------------------------------*/
531 /* newiCode for conditional statements */
532 /*-----------------------------------------------------------------*/
534 newiCodeCondition (operand * condition,
540 if (IS_VOID(OP_SYMBOL(condition)->type)) {
541 werror(E_VOID_VALUE_USED);
544 ic = newiCode (IFX, NULL, NULL);
545 IC_COND (ic) = condition;
546 IC_TRUE (ic) = trueLabel;
547 IC_FALSE (ic) = falseLabel;
551 /*-----------------------------------------------------------------*/
552 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
553 /*-----------------------------------------------------------------*/
555 newiCodeLabelGoto (int op, symbol * label)
559 ic = newiCode (op, NULL, NULL);
561 ic->argLabel.label = label;
563 IC_RIGHT (ic) = NULL;
564 IC_RESULT (ic) = NULL;
568 /*-----------------------------------------------------------------*/
569 /* newiTemp - allocate & return a newItemp Variable */
570 /*-----------------------------------------------------------------*/
577 sprintf (buffer, "%s", s);
579 sprintf (buffer, "iTemp%d", iTempNum++);
580 itmp = newSymbol (buffer, 1);
581 strcpy (itmp->rname, itmp->name);
587 /*-----------------------------------------------------------------*/
588 /* newiTempLabel - creates a temp variable label */
589 /*-----------------------------------------------------------------*/
591 newiTempLabel (char *s)
595 /* check if this alredy exists */
596 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
600 itmplbl = newSymbol (s, 1);
603 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
604 itmplbl = newSymbol (buffer, 1);
609 itmplbl->key = labelKey++;
610 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
614 /*-----------------------------------------------------------------*/
615 /* newiTempPreheaderLabel - creates a new preheader label */
616 /*-----------------------------------------------------------------*/
618 newiTempPreheaderLabel ()
622 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
623 itmplbl = newSymbol (buffer, 1);
627 itmplbl->key = labelKey++;
628 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
633 /*-----------------------------------------------------------------*/
634 /* initiCode - initialises some iCode related stuff */
635 /*-----------------------------------------------------------------*/
642 /*-----------------------------------------------------------------*/
643 /* copyiCode - make a copy of the iCode given */
644 /*-----------------------------------------------------------------*/
646 copyiCode (iCode * ic)
648 iCode *nic = newiCode (ic->op, NULL, NULL);
650 nic->lineno = ic->lineno;
651 nic->filename = ic->filename;
652 nic->block = ic->block;
653 nic->level = ic->level;
654 nic->parmBytes = ic->parmBytes;
656 /* deal with the special cases first */
660 IC_COND (nic) = operandFromOperand (IC_COND (ic));
661 IC_TRUE (nic) = IC_TRUE (ic);
662 IC_FALSE (nic) = IC_FALSE (ic);
666 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
667 IC_JTLABELS (nic) = IC_JTLABELS (ic);
672 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
673 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
674 IC_ARGS (nic) = IC_ARGS (ic);
678 IC_INLINE (nic) = IC_INLINE (ic);
682 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
686 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
687 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
688 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
694 /*-----------------------------------------------------------------*/
695 /* getTableEntry - gets the table entry for the given operator */
696 /*-----------------------------------------------------------------*/
698 getTableEntry (int oper)
702 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
703 if (oper == codeTable[i].icode)
704 return &codeTable[i];
709 /*-----------------------------------------------------------------*/
710 /* newiTempOperand - new intermediate temp operand */
711 /*-----------------------------------------------------------------*/
713 newiTempOperand (sym_link * type, char throwType)
716 operand *op = newOperand ();
720 itmp = newiTemp (NULL);
722 etype = getSpec (type);
724 if (IS_LITERAL (etype))
727 /* copy the type information */
729 itmp->etype = getSpec (itmp->type = (throwType ? type :
730 copyLinkChain (type)));
731 if (IS_LITERAL (itmp->etype))
733 SPEC_SCLS (itmp->etype) = S_REGISTER;
734 SPEC_OCLS (itmp->etype) = reg;
737 op->operand.symOperand = itmp;
738 op->key = itmp->key = ++operandKey;
742 /*-----------------------------------------------------------------*/
743 /* operandType - returns the type chain for an operand */
744 /*-----------------------------------------------------------------*/
746 operandType (operand * op)
748 /* depending on type of operand */
753 return op->operand.valOperand->type;
756 return op->operand.symOperand->type;
759 return op->operand.typeOperand;
761 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
762 " operand type not known ");
763 assert (0); /* should never come here */
764 /* Just to keep the compiler happy */
765 return (sym_link *) 0;
769 /*-----------------------------------------------------------------*/
770 /* isParamterToCall - will return 1 if op is a parameter to args */
771 /*-----------------------------------------------------------------*/
773 isParameterToCall (value * args, operand * op)
780 isSymbolEqual (op->operand.symOperand, tval->sym))
787 /*-----------------------------------------------------------------*/
788 /* isOperandGlobal - return 1 if operand is a global variable */
789 /*-----------------------------------------------------------------*/
791 isOperandGlobal (operand * op)
799 if (op->type == SYMBOL &&
800 (op->operand.symOperand->level == 0 ||
801 IS_STATIC (op->operand.symOperand->etype) ||
802 IS_EXTERN (op->operand.symOperand->etype))
809 /*-----------------------------------------------------------------*/
810 /* isOperandVolatile - return 1 if the operand is volatile */
811 /*-----------------------------------------------------------------*/
813 isOperandVolatile (operand * op, bool chkTemp)
818 if (IS_ITEMP (op) && !chkTemp)
821 opetype = getSpec (optype = operandType (op));
823 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
826 if (IS_VOLATILE (opetype))
831 /*-----------------------------------------------------------------*/
832 /* isOperandLiteral - returns 1 if an operand contains a literal */
833 /*-----------------------------------------------------------------*/
835 isOperandLiteral (operand * op)
842 opetype = getSpec (operandType (op));
844 if (IS_LITERAL (opetype))
849 /*-----------------------------------------------------------------*/
850 /* isOperandInFarSpace - will return true if operand is in farSpace */
851 /*-----------------------------------------------------------------*/
853 isOperandInFarSpace (operand * op)
863 if (!IS_TRUE_SYMOP (op))
866 etype = SPIL_LOC (op)->etype;
872 etype = getSpec (operandType (op));
874 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
877 /*-----------------------------------------------------------------*/
878 /* isOperandOnStack - will return true if operand is on stack */
879 /*-----------------------------------------------------------------*/
881 isOperandOnStack (operand * op)
891 etype = getSpec (operandType (op));
893 return ((IN_STACK (etype)) ? TRUE : FALSE);
896 /*-----------------------------------------------------------------*/
897 /* operandLitValue - literal value of an operand */
898 /*-----------------------------------------------------------------*/
900 operandLitValue (operand * op)
902 assert (isOperandLiteral (op));
904 return floatFromVal (op->operand.valOperand);
907 /*-----------------------------------------------------------------*/
908 /* operandOperation - perforoms operations on operands */
909 /*-----------------------------------------------------------------*/
911 operandOperation (operand * left, operand * right,
912 int op, sym_link * type)
914 sym_link *let , *ret=NULL;
915 operand *retval = (operand *) 0;
917 assert (isOperandLiteral (left));
918 let = getSpec(operandType(left));
920 assert (isOperandLiteral (right));
921 ret = getSpec(operandType(left));
927 retval = operandFromValue (valCastLiteral (type,
928 operandLitValue (left) +
929 operandLitValue (right)));
932 retval = operandFromValue (valCastLiteral (type,
933 operandLitValue (left) -
934 operandLitValue (right)));
937 retval = operandFromValue (valCastLiteral (type,
938 operandLitValue (left) *
939 operandLitValue (right)));
942 if ((unsigned long) operandLitValue (right) == 0)
944 werror (E_DIVIDE_BY_ZERO);
949 retval = operandFromValue (valCastLiteral (type,
950 operandLitValue (left) /
951 operandLitValue (right)));
954 if ((unsigned long) operandLitValue (right) == 0) {
955 werror (E_DIVIDE_BY_ZERO);
959 retval = operandFromLit ((SPEC_USIGN(let) ?
960 (unsigned long) operandLitValue (left) :
961 (long) operandLitValue (left)) %
963 (unsigned long) operandLitValue (right) :
964 (long) operandLitValue (right)));
968 retval = operandFromLit (((SPEC_USIGN(let) ?
969 (unsigned long) operandLitValue (left) :
970 (long) operandLitValue (left)) <<
972 (unsigned long) operandLitValue (right) :
973 (long) operandLitValue (right))));
976 retval = operandFromLit (((SPEC_USIGN(let) ?
977 (unsigned long) operandLitValue (left) :
978 (long) operandLitValue (left)) >>
980 (unsigned long) operandLitValue (right) :
981 (long) operandLitValue (right))));
984 retval = operandFromLit (operandLitValue (left) ==
985 operandLitValue (right));
988 retval = operandFromLit (operandLitValue (left) <
989 operandLitValue (right));
992 retval = operandFromLit (operandLitValue (left) <=
993 operandLitValue (right));
996 retval = operandFromLit (operandLitValue (left) !=
997 operandLitValue (right));
1000 retval = operandFromLit (operandLitValue (left) >
1001 operandLitValue (right));
1004 retval = operandFromLit (operandLitValue (left) >=
1005 operandLitValue (right));
1008 retval = operandFromLit ((unsigned long) operandLitValue (left) &
1009 (unsigned long) operandLitValue (right));
1012 retval = operandFromLit ((unsigned long) operandLitValue (left) |
1013 (unsigned long) operandLitValue (right));
1016 retval = operandFromLit ((unsigned long) operandLitValue (left) ^
1017 (unsigned long) operandLitValue (right));
1020 retval = operandFromLit (operandLitValue (left) &&
1021 operandLitValue (right));
1024 retval = operandFromLit (operandLitValue (left) ||
1025 operandLitValue (right));
1029 long i = (long) operandLitValue (left);
1031 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1037 long i = (long) operandLitValue (left);
1039 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1045 retval = operandFromLit (-1 * operandLitValue (left));
1049 retval = operandFromLit (~((long) operandLitValue (left)));
1053 retval = operandFromLit (!operandLitValue (left));
1057 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1058 " operandOperation invalid operator ");
1066 /*-----------------------------------------------------------------*/
1067 /* isOperandEqual - compares two operand & return 1 if they r = */
1068 /*-----------------------------------------------------------------*/
1070 isOperandEqual (operand * left, operand * right)
1072 /* if the pointers are equal then they are equal */
1076 /* if either of them null then false */
1077 if (!left || !right)
1080 if (left->type != right->type)
1083 if (IS_SYMOP (left) && IS_SYMOP (right))
1084 return left->key == right->key;
1086 /* if types are the same */
1090 return isSymbolEqual (left->operand.symOperand,
1091 right->operand.symOperand);
1093 return (floatFromVal (left->operand.valOperand) ==
1094 floatFromVal (right->operand.valOperand));
1096 if (compareType (left->operand.typeOperand,
1097 right->operand.typeOperand) == 1)
1104 /*-----------------------------------------------------------------*/
1105 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1106 /*-----------------------------------------------------------------*/
1108 isiCodeEqual (iCode * left, iCode * right)
1110 /* if the same pointer */
1114 /* if either of them null */
1115 if (!left || !right)
1118 /* if operand are the same */
1119 if (left->op == right->op)
1122 /* compare all the elements depending on type */
1123 if (left->op != IFX)
1125 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1127 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1133 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1135 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1137 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1145 /*-----------------------------------------------------------------*/
1146 /* newiTempFromOp - create a temp Operand with same attributes */
1147 /*-----------------------------------------------------------------*/
1149 newiTempFromOp (operand * op)
1159 nop = newiTempOperand (operandType (op), TRUE);
1160 nop->isaddr = op->isaddr;
1161 nop->isvolatile = op->isvolatile;
1162 nop->isGlobal = op->isGlobal;
1163 nop->isLiteral = op->isLiteral;
1164 nop->usesDefs = op->usesDefs;
1165 nop->isParm = op->isParm;
1169 /*-----------------------------------------------------------------*/
1170 /* operand from operand - creates an operand holder for the type */
1171 /*-----------------------------------------------------------------*/
1173 operandFromOperand (operand * op)
1179 nop = newOperand ();
1180 nop->type = op->type;
1181 nop->isaddr = op->isaddr;
1183 nop->isvolatile = op->isvolatile;
1184 nop->isGlobal = op->isGlobal;
1185 nop->isLiteral = op->isLiteral;
1186 nop->usesDefs = op->usesDefs;
1187 nop->isParm = op->isParm;
1192 nop->operand.symOperand = op->operand.symOperand;
1195 nop->operand.valOperand = op->operand.valOperand;
1198 nop->operand.typeOperand = op->operand.typeOperand;
1205 /*-----------------------------------------------------------------*/
1206 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1207 /*-----------------------------------------------------------------*/
1209 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1211 operand *nop = operandFromOperand (op);
1213 if (nop->type == SYMBOL)
1215 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1216 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1222 /*-----------------------------------------------------------------*/
1223 /* operandFromSymbol - creates an operand from a symbol */
1224 /*-----------------------------------------------------------------*/
1226 operandFromSymbol (symbol * sym)
1231 /* if the symbol's type is a literal */
1232 /* then it is an enumerator type */
1233 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1234 return operandFromValue (valFromType (sym->etype));
1237 sym->key = ++operandKey;
1239 /* if this an implicit variable, means struct/union */
1240 /* member so just return it */
1241 if (sym->implicit || IS_FUNC (sym->type))
1245 op->operand.symOperand = sym;
1247 op->isvolatile = isOperandVolatile (op, TRUE);
1248 op->isGlobal = isOperandGlobal (op);
1252 /* under the following conditions create a
1253 register equivalent for a local symbol */
1254 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1255 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1256 /* (!TARGET_IS_DS390)) && */
1257 (!(options.model == MODEL_FLAT24)) ) &&
1258 options.stackAuto == 0)
1261 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1262 !IS_FUNC (sym->type) && /* not a function */
1263 !sym->_isparm && /* not a parameter */
1264 sym->level && /* is a local variable */
1265 !sym->addrtaken && /* whose address has not been taken */
1266 !sym->reqv && /* does not already have a register euivalence */
1267 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1268 !IS_STATIC (sym->etype) && /* and not declared static */
1269 !sym->islbl && /* not a label */
1270 ok && /* farspace check */
1271 !IS_BITVAR (sym->etype) /* not a bit variable */
1275 /* we will use it after all optimizations
1276 and before liveRange calculation */
1277 sym->reqv = newiTempOperand (sym->type, 0);
1278 sym->reqv->key = sym->key;
1279 OP_SYMBOL (sym->reqv)->key = sym->key;
1280 OP_SYMBOL (sym->reqv)->isreqv = 1;
1281 OP_SYMBOL (sym->reqv)->islocal = 1;
1282 SPIL_LOC (sym->reqv) = sym;
1285 if (!IS_AGGREGATE (sym->type))
1289 op->operand.symOperand = sym;
1292 op->isvolatile = isOperandVolatile (op, TRUE);
1293 op->isGlobal = isOperandGlobal (op);
1294 op->isPtr = IS_PTR (operandType (op));
1295 op->isParm = sym->_isparm;
1300 /* itemp = &[_symbol] */
1302 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1303 IC_LEFT (ic)->type = SYMBOL;
1304 IC_LEFT (ic)->operand.symOperand = sym;
1305 IC_LEFT (ic)->key = sym->key;
1306 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1307 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1308 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1311 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1312 if (IS_ARRAY (sym->type))
1314 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1315 IC_RESULT (ic)->isaddr = 0;
1318 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1320 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1324 return IC_RESULT (ic);
1327 /*-----------------------------------------------------------------*/
1328 /* operandFromValue - creates an operand from value */
1329 /*-----------------------------------------------------------------*/
1331 operandFromValue (value * val)
1335 /* if this is a symbol then do the symbol thing */
1337 return operandFromSymbol (val->sym);
1339 /* this is not a symbol */
1342 op->operand.valOperand = val;
1343 op->isLiteral = isOperandLiteral (op);
1347 /*-----------------------------------------------------------------*/
1348 /* operandFromLink - operand from typeChain */
1349 /*-----------------------------------------------------------------*/
1351 operandFromLink (sym_link * type)
1355 /* operand from sym_link */
1361 op->operand.typeOperand = copyLinkChain (type);
1365 /*-----------------------------------------------------------------*/
1366 /* operandFromLit - makes an operand from a literal value */
1367 /*-----------------------------------------------------------------*/
1369 operandFromLit (double i)
1371 return operandFromValue (valueFromLit (i));
1374 /*-----------------------------------------------------------------*/
1375 /* operandFromAst - creates an operand from an ast */
1376 /*-----------------------------------------------------------------*/
1378 operandFromAst (ast * tree,int lvl)
1384 /* depending on type do */
1388 return ast2iCode (tree,lvl+1);
1392 return operandFromValue (tree->opval.val);
1396 return operandFromLink (tree->opval.lnk);
1400 /* Just to keep the comiler happy */
1401 return (operand *) 0;
1404 /*-----------------------------------------------------------------*/
1405 /* setOperandType - sets the operand's type to the given type */
1406 /*-----------------------------------------------------------------*/
1408 setOperandType (operand * op, sym_link * type)
1410 /* depending on the type of operand */
1415 op->operand.valOperand->etype =
1416 getSpec (op->operand.valOperand->type =
1417 copyLinkChain (type));
1421 if (op->operand.symOperand->isitmp)
1422 op->operand.symOperand->etype =
1423 getSpec (op->operand.symOperand->type =
1424 copyLinkChain (type));
1426 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1427 "attempt to modify type of source");
1431 op->operand.typeOperand = copyLinkChain (type);
1436 /*-----------------------------------------------------------------*/
1437 /* Get size in byte of ptr need to access an array */
1438 /*-----------------------------------------------------------------*/
1440 getArraySizePtr (operand * op)
1442 sym_link *ltype = operandType(op);
1446 int size = getSize(ltype);
1447 return(IS_GENPTR(ltype)?(size-1):size);
1452 sym_link *letype = getSpec(ltype);
1453 switch (PTR_TYPE (SPEC_OCLS (letype)))
1465 return (GPTRSIZE-1);
1474 /*-----------------------------------------------------------------*/
1475 /* perform "usual unary conversions" */
1476 /*-----------------------------------------------------------------*/
1478 usualUnaryConversions (operand * op)
1480 if (IS_INTEGRAL (operandType (op)))
1482 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1485 return geniCodeCast (INTTYPE, op, TRUE);
1491 /*-----------------------------------------------------------------*/
1492 /* perform "usual binary conversions" */
1493 /*-----------------------------------------------------------------*/
1495 usualBinaryConversions (operand ** op1, operand ** op2)
1498 sym_link *rtype = operandType (*op2);
1499 sym_link *ltype = operandType (*op1);
1501 ctype = computeType (ltype, rtype);
1502 *op1 = geniCodeCast (ctype, *op1, TRUE);
1503 *op2 = geniCodeCast (ctype, *op2, TRUE);
1508 /*-----------------------------------------------------------------*/
1509 /* geniCodeValueAtAddress - generate intermeditate code for value */
1511 /*-----------------------------------------------------------------*/
1513 geniCodeRValue (operand * op, bool force)
1516 sym_link *type = operandType (op);
1517 sym_link *etype = getSpec (type);
1519 /* if this is an array & already */
1520 /* an address then return this */
1521 if (IS_AGGREGATE (type) ||
1522 (IS_PTR (type) && !force && !op->isaddr))
1523 return operandFromOperand (op);
1525 /* if this is not an address then must be */
1526 /* rvalue already so return this one */
1530 /* if this is not a temp symbol then */
1531 if (!IS_ITEMP (op) &&
1533 !IN_FARSPACE (SPEC_OCLS (etype)))
1535 op = operandFromOperand (op);
1540 if (IS_SPEC (type) &&
1541 IS_TRUE_SYMOP (op) &&
1542 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1543 /* TARGET_IS_DS390)) */
1544 (options.model == MODEL_FLAT24) ))
1546 op = operandFromOperand (op);
1551 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1552 if (IS_PTR (type) && op->isaddr && force)
1555 type = copyLinkChain (type);
1557 IC_RESULT (ic) = newiTempOperand (type, 1);
1558 IC_RESULT (ic)->isaddr = 0;
1560 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1562 /* if the right is a symbol */
1563 if (op->type == SYMBOL)
1564 IC_RESULT (ic)->operand.symOperand->args =
1565 op->operand.symOperand->args;
1568 return IC_RESULT (ic);
1571 /*-----------------------------------------------------------------*/
1572 /* geniCodeCast - changes the value from one type to another */
1573 /*-----------------------------------------------------------------*/
1575 geniCodeCast (sym_link * type, operand * op, bool implicit)
1579 sym_link *opetype = getSpec (optype = operandType (op));
1583 /* one of them has size zero then error */
1584 if (IS_VOID (optype))
1586 werror (E_CAST_ZERO);
1590 /* if the operand is already the desired type then do nothing */
1591 if (compareType (type, optype) == 1)
1594 /* if this is a literal then just change the type & return */
1595 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1596 return operandFromValue (valCastLiteral (type,
1597 operandLitValue (op)));
1599 /* if casting to/from pointers, do some checking */
1600 if (IS_PTR(type)) { // to a pointer
1601 if (!IS_PTR(optype) && !IS_FUNC(optype)) { // from a non pointer
1602 if (IS_INTEGRAL(optype)) {
1603 // maybe this is NULL, than it's ok.
1604 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1605 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1606 // no way to set the storage
1607 if (IS_LITERAL(optype)) {
1608 werror(E_LITERAL_GENERIC);
1611 werror(E_NONPTR2_GENPTR);
1614 } else if (implicit) {
1615 werror(W_INTEGRAL2PTR_NOCAST);
1620 // shouldn't do that with float, array or structure unless to void
1621 if (!IS_VOID(getSpec(type)) &&
1622 !(IS_CODEPTR(type) && IS_FUNC(optype))) {
1623 werror(E_INCOMPAT_TYPES);
1627 } else { // from a pointer to a pointer
1628 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1629 if (implicit) { // if not to generic, they have to match
1630 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1631 werror(E_INCOMPAT_PTYPES);
1637 } else { // to a non pointer
1638 if (IS_PTR(optype)) { // from a pointer
1639 if (implicit) { // sneaky
1640 if (IS_INTEGRAL(type)) {
1641 werror(W_PTR2INTEGRAL_NOCAST);
1643 } else { // shouldn't do that with float, array or structure
1644 werror(E_INCOMPAT_TYPES);
1651 /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
1652 implicit?"(implicit)":"", errors); */
1653 fprintf (stderr, "from type '");
1654 printTypeChain (optype, stderr);
1655 fprintf (stderr, "' to type '");
1656 printTypeChain (type, stderr);
1657 fprintf (stderr, "'\n");
1660 /* if they are the same size create an assignment */
1661 if (getSize (type) == getSize (optype) &&
1662 !IS_BITFIELD (type) &&
1664 !IS_FLOAT (optype) &&
1665 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1666 (!IS_SPEC (type) && !IS_SPEC (optype))))
1669 ic = newiCode ('=', NULL, op);
1670 IC_RESULT (ic) = newiTempOperand (type, 0);
1671 SPIL_LOC (IC_RESULT (ic)) =
1672 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1673 IC_RESULT (ic)->isaddr = 0;
1677 ic = newiCode (CAST, operandFromLink (type),
1678 geniCodeRValue (op, FALSE));
1680 IC_RESULT (ic) = newiTempOperand (type, 0);
1683 /* preserve the storage class & output class */
1684 /* of the original variable */
1685 restype = getSpec (operandType (IC_RESULT (ic)));
1686 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1687 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1690 return IC_RESULT (ic);
1693 /*-----------------------------------------------------------------*/
1694 /* geniCodeLabel - will create a Label */
1695 /*-----------------------------------------------------------------*/
1697 geniCodeLabel (symbol * label)
1701 ic = newiCodeLabelGoto (LABEL, label);
1705 /*-----------------------------------------------------------------*/
1706 /* geniCodeGoto - will create a Goto */
1707 /*-----------------------------------------------------------------*/
1709 geniCodeGoto (symbol * label)
1713 ic = newiCodeLabelGoto (GOTO, label);
1717 /*-----------------------------------------------------------------*/
1718 /* geniCodeMultiply - gen intermediate code for multiplication */
1719 /*-----------------------------------------------------------------*/
1721 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1728 /* if they are both literal then we know the result */
1729 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1730 return operandFromValue (valMult (left->operand.valOperand,
1731 right->operand.valOperand));
1733 if (IS_LITERAL(retype)) {
1734 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1737 resType = usualBinaryConversions (&left, &right);
1739 rtype = operandType (right);
1740 retype = getSpec (rtype);
1741 ltype = operandType (left);
1742 letype = getSpec (ltype);
1746 SPEC_NOUN(getSpec(resType))=V_INT;
1749 /* if the right is a literal & power of 2 */
1750 /* then make it a left shift */
1751 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1752 efficient in most cases than 2 bytes result = 2 bytes << literal
1753 if port has 1 byte muldiv */
1754 if (p2 && !IS_FLOAT (letype) &&
1755 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1756 (port->support.muldiv == 1)))
1758 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1760 /* LEFT_OP need same size for left and result, */
1761 left = geniCodeCast (resType, left, TRUE);
1762 ltype = operandType (left);
1764 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1768 ic = newiCode ('*', left, right); /* normal multiplication */
1769 /* if the size left or right > 1 then support routine */
1770 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1774 IC_RESULT (ic) = newiTempOperand (resType, 1);
1777 return IC_RESULT (ic);
1780 /*-----------------------------------------------------------------*/
1781 /* geniCodeDivision - gen intermediate code for division */
1782 /*-----------------------------------------------------------------*/
1784 geniCodeDivision (operand * left, operand * right)
1789 sym_link *rtype = operandType (right);
1790 sym_link *retype = getSpec (rtype);
1791 sym_link *ltype = operandType (left);
1792 sym_link *letype = getSpec (ltype);
1794 resType = usualBinaryConversions (&left, &right);
1796 /* if the right is a literal & power of 2 */
1797 /* then make it a right shift */
1798 if (IS_LITERAL (retype) &&
1799 !IS_FLOAT (letype) &&
1800 (p2 = powof2 ((unsigned long)
1801 floatFromVal (right->operand.valOperand)))) {
1802 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1806 ic = newiCode ('/', left, right); /* normal division */
1807 /* if the size left or right > 1 then support routine */
1808 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1811 IC_RESULT (ic) = newiTempOperand (resType, 0);
1814 return IC_RESULT (ic);
1816 /*-----------------------------------------------------------------*/
1817 /* geniCodeModulus - gen intermediate code for modulus */
1818 /*-----------------------------------------------------------------*/
1820 geniCodeModulus (operand * left, operand * right)
1826 /* if they are both literal then we know the result */
1827 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1828 return operandFromValue (valMod (left->operand.valOperand,
1829 right->operand.valOperand));
1831 resType = usualBinaryConversions (&left, &right);
1833 /* now they are the same size */
1834 ic = newiCode ('%', left, right);
1836 /* if the size left or right > 1 then support routine */
1837 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1839 IC_RESULT (ic) = newiTempOperand (resType, 0);
1842 return IC_RESULT (ic);
1845 /*-----------------------------------------------------------------*/
1846 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1847 /*-----------------------------------------------------------------*/
1849 geniCodePtrPtrSubtract (operand * left, operand * right)
1855 /* if they are both literals then */
1856 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1858 result = operandFromValue (valMinus (left->operand.valOperand,
1859 right->operand.valOperand));
1863 ic = newiCode ('-', left, right);
1865 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1869 return geniCodeDivision (result,
1870 operandFromLit (getSize (ltype->next)));
1873 /*-----------------------------------------------------------------*/
1874 /* geniCodeSubtract - generates code for subtraction */
1875 /*-----------------------------------------------------------------*/
1877 geniCodeSubtract (operand * left, operand * right)
1884 /* if they both pointers then */
1885 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1886 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1887 return geniCodePtrPtrSubtract (left, right);
1889 /* if they are both literal then we know the result */
1890 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1891 && left->isLiteral && right->isLiteral)
1892 return operandFromValue (valMinus (left->operand.valOperand,
1893 right->operand.valOperand));
1895 /* if left is an array or pointer */
1896 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1898 isarray = left->isaddr;
1899 right = geniCodeMultiply (right,
1900 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1901 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1904 { /* make them the same size */
1905 resType = usualBinaryConversions (&left, &right);
1908 ic = newiCode ('-', left, right);
1910 IC_RESULT (ic) = newiTempOperand (resType, 1);
1911 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1913 /* if left or right is a float */
1914 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1918 return IC_RESULT (ic);
1921 /*-----------------------------------------------------------------*/
1922 /* geniCodeAdd - generates iCode for addition */
1923 /*-----------------------------------------------------------------*/
1925 geniCodeAdd (operand * left, operand * right,int lvl)
1933 /* if left is an array then array access */
1934 if (IS_ARRAY (ltype))
1935 return geniCodeArray (left, right,lvl);
1937 /* if the right side is LITERAL zero */
1938 /* return the left side */
1939 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1942 /* if left is literal zero return right */
1943 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1946 /* if left is an array or pointer then size */
1949 isarray = left->isaddr;
1950 // there is no need to multiply with 1
1951 if (getSize(ltype->next)!=1) {
1952 size = operandFromLit (getSize (ltype->next));
1953 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1955 resType = copyLinkChain (ltype);
1958 { /* make them the same size */
1959 resType = usualBinaryConversions (&left, &right);
1962 /* if they are both literals then we know */
1963 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1964 && left->isLiteral && right->isLiteral)
1965 return operandFromValue (valPlus (valFromType (letype),
1966 valFromType (retype)));
1968 ic = newiCode ('+', left, right);
1970 IC_RESULT (ic) = newiTempOperand (resType, 1);
1971 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1973 /* if left or right is a float then support
1975 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1980 return IC_RESULT (ic);
1984 /*-----------------------------------------------------------------*/
1985 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1986 /*-----------------------------------------------------------------*/
1988 aggrToPtr (sym_link * type, bool force)
1994 if (IS_PTR (type) && !force)
1997 etype = getSpec (type);
2001 /* if the output class is generic */
2002 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2003 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2005 /* if the variable was declared a constant */
2006 /* then the pointer points to a constant */
2007 if (IS_CONSTANT (etype))
2008 DCL_PTR_CONST (ptype) = 1;
2010 /* the variable was volatile then pointer to volatile */
2011 if (IS_VOLATILE (etype))
2012 DCL_PTR_VOLATILE (ptype) = 1;
2016 /*-----------------------------------------------------------------*/
2017 /* geniCodeArray2Ptr - array to pointer */
2018 /*-----------------------------------------------------------------*/
2020 geniCodeArray2Ptr (operand * op)
2022 sym_link *optype = operandType (op);
2023 sym_link *opetype = getSpec (optype);
2025 /* set the pointer depending on the storage class */
2026 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2027 DCL_PTR_CONST (optype) = port->mem.code_ro;
2030 /* if the variable was declared a constant */
2031 /* then the pointer points to a constant */
2032 if (IS_CONSTANT (opetype))
2033 DCL_PTR_CONST (optype) = 1;
2035 /* the variable was volatile then pointer to volatile */
2036 if (IS_VOLATILE (opetype))
2037 DCL_PTR_VOLATILE (optype) = 1;
2043 /*-----------------------------------------------------------------*/
2044 /* geniCodeArray - array access */
2045 /*-----------------------------------------------------------------*/
2047 geniCodeArray (operand * left, operand * right,int lvl)
2050 sym_link *ltype = operandType (left);
2054 if (IS_PTR (ltype->next) && left->isaddr)
2056 left = geniCodeRValue (left, FALSE);
2058 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2061 right = geniCodeMultiply (right,
2062 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2064 /* we can check for limits here */
2065 if (isOperandLiteral (right) &&
2068 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2070 werror (E_ARRAY_BOUND);
2071 right = operandFromLit (0);
2074 ic = newiCode ('+', left, right);
2076 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2077 !IS_AGGREGATE (ltype->next) &&
2078 !IS_PTR (ltype->next))
2079 ? ltype : ltype->next), 0);
2081 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2083 return IC_RESULT (ic);
2086 /*-----------------------------------------------------------------*/
2087 /* geniCodeStruct - generates intermediate code for structres */
2088 /*-----------------------------------------------------------------*/
2090 geniCodeStruct (operand * left, operand * right, bool islval)
2093 sym_link *type = operandType (left);
2094 sym_link *etype = getSpec (type);
2096 symbol *element = getStructElement (SPEC_STRUCT (etype),
2097 right->operand.symOperand);
2099 /* add the offset */
2100 ic = newiCode ('+', left, operandFromLit (element->offset));
2102 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2104 /* preserve the storage & output class of the struct */
2105 /* as well as the volatile attribute */
2106 retype = getSpec (operandType (IC_RESULT (ic)));
2107 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2108 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2109 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2111 if (IS_PTR (element->type))
2112 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2114 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2118 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2121 /*-----------------------------------------------------------------*/
2122 /* geniCodePostInc - generate int code for Post increment */
2123 /*-----------------------------------------------------------------*/
2125 geniCodePostInc (operand * op)
2129 sym_link *optype = operandType (op);
2131 operand *rv = (IS_ITEMP (op) ?
2132 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2134 sym_link *rvtype = operandType (rv);
2137 /* if this is not an address we have trouble */
2140 werror (E_LVALUE_REQUIRED, "++");
2144 rOp = newiTempOperand (rvtype, 0);
2145 OP_SYMBOL(rOp)->noSpilLoc = 1;
2148 OP_SYMBOL(rv)->noSpilLoc = 1;
2150 geniCodeAssign (rOp, rv, 0);
2152 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2153 if (IS_FLOAT (rvtype))
2154 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2156 ic = newiCode ('+', rv, operandFromLit (size));
2158 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2161 geniCodeAssign (op, result, 0);
2167 /*-----------------------------------------------------------------*/
2168 /* geniCodePreInc - generate code for preIncrement */
2169 /*-----------------------------------------------------------------*/
2171 geniCodePreInc (operand * op)
2174 sym_link *optype = operandType (op);
2175 operand *rop = (IS_ITEMP (op) ?
2176 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2178 sym_link *roptype = operandType (rop);
2184 werror (E_LVALUE_REQUIRED, "++");
2189 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2190 if (IS_FLOAT (roptype))
2191 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2193 ic = newiCode ('+', rop, operandFromLit (size));
2194 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2198 return geniCodeAssign (op, result, 0);
2201 /*-----------------------------------------------------------------*/
2202 /* geniCodePostDec - generates code for Post decrement */
2203 /*-----------------------------------------------------------------*/
2205 geniCodePostDec (operand * op)
2209 sym_link *optype = operandType (op);
2211 operand *rv = (IS_ITEMP (op) ?
2212 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2214 sym_link *rvtype = operandType (rv);
2217 /* if this is not an address we have trouble */
2220 werror (E_LVALUE_REQUIRED, "--");
2224 rOp = newiTempOperand (rvtype, 0);
2225 OP_SYMBOL(rOp)->noSpilLoc = 1;
2228 OP_SYMBOL(rv)->noSpilLoc = 1;
2230 geniCodeAssign (rOp, rv, 0);
2232 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2233 if (IS_FLOAT (rvtype))
2234 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2236 ic = newiCode ('-', rv, operandFromLit (size));
2238 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2241 geniCodeAssign (op, result, 0);
2247 /*-----------------------------------------------------------------*/
2248 /* geniCodePreDec - generate code for pre decrement */
2249 /*-----------------------------------------------------------------*/
2251 geniCodePreDec (operand * op)
2254 sym_link *optype = operandType (op);
2255 operand *rop = (IS_ITEMP (op) ?
2256 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2258 sym_link *roptype = operandType (rop);
2264 werror (E_LVALUE_REQUIRED, "--");
2269 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2270 if (IS_FLOAT (roptype))
2271 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2273 ic = newiCode ('-', rop, operandFromLit (size));
2274 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2278 return geniCodeAssign (op, result, 0);
2282 /*-----------------------------------------------------------------*/
2283 /* geniCodeBitwise - gen int code for bitWise operators */
2284 /*-----------------------------------------------------------------*/
2286 geniCodeBitwise (operand * left, operand * right,
2287 int oper, sym_link * resType)
2291 left = geniCodeCast (resType, left, TRUE);
2292 right = geniCodeCast (resType, right, TRUE);
2294 ic = newiCode (oper, left, right);
2295 IC_RESULT (ic) = newiTempOperand (resType, 0);
2298 return IC_RESULT (ic);
2301 /*-----------------------------------------------------------------*/
2302 /* geniCodeAddressOf - gens icode for '&' address of operator */
2303 /*-----------------------------------------------------------------*/
2305 geniCodeAddressOf (operand * op)
2309 sym_link *optype = operandType (op);
2310 sym_link *opetype = getSpec (optype);
2312 /* lvalue check already done in decorateType */
2313 /* this must be a lvalue */
2314 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2315 /* werror (E_LVALUE_REQUIRED,"&"); */
2320 p->class = DECLARATOR;
2322 /* set the pointer depending on the storage class */
2323 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2324 DCL_PTR_CONST (p) = port->mem.code_ro;
2326 /* make sure we preserve the const & volatile */
2327 if (IS_CONSTANT (opetype))
2328 DCL_PTR_CONST (p) = 1;
2330 if (IS_VOLATILE (opetype))
2331 DCL_PTR_VOLATILE (p) = 1;
2333 p->next = copyLinkChain (optype);
2335 /* if already a temp */
2338 setOperandType (op, p);
2343 /* other wise make this of the type coming in */
2344 ic = newiCode (ADDRESS_OF, op, NULL);
2345 IC_RESULT (ic) = newiTempOperand (p, 1);
2346 IC_RESULT (ic)->isaddr = 0;
2348 return IC_RESULT (ic);
2350 /*-----------------------------------------------------------------*/
2351 /* setOClass - sets the output class depending on the pointer type */
2352 /*-----------------------------------------------------------------*/
2354 setOClass (sym_link * ptr, sym_link * spec)
2356 switch (DCL_TYPE (ptr))
2359 SPEC_OCLS (spec) = data;
2363 SPEC_OCLS (spec) = generic;
2367 SPEC_OCLS (spec) = xdata;
2371 SPEC_OCLS (spec) = code;
2375 SPEC_OCLS (spec) = idata;
2379 SPEC_OCLS (spec) = xstack;
2383 SPEC_OCLS (spec) = eeprom;
2392 /*-----------------------------------------------------------------*/
2393 /* geniCodeDerefPtr - dereference pointer with '*' */
2394 /*-----------------------------------------------------------------*/
2396 geniCodeDerefPtr (operand * op,int lvl)
2398 sym_link *rtype, *retype;
2399 sym_link *optype = operandType (op);
2401 /* if this is a pointer then generate the rvalue */
2402 if (IS_PTR (optype))
2404 if (IS_TRUE_SYMOP (op))
2407 op = geniCodeRValue (op, TRUE);
2410 op = geniCodeRValue (op, TRUE);
2413 /* now get rid of the pointer part */
2414 if (isLvaluereq(lvl) && IS_ITEMP (op))
2416 retype = getSpec (rtype = copyLinkChain (optype));
2420 retype = getSpec (rtype = copyLinkChain (optype->next));
2423 /* if this is a pointer then outputclass needs 2b updated */
2424 if (IS_PTR (optype))
2425 setOClass (optype, retype);
2427 op->isGptr = IS_GENPTR (optype);
2429 /* if the pointer was declared as a constant */
2430 /* then we cannot allow assignment to the derefed */
2431 if (IS_PTR_CONST (optype))
2432 SPEC_CONST (retype) = 1;
2434 op->isaddr = (IS_PTR (rtype) ||
2435 IS_STRUCT (rtype) ||
2440 if (!isLvaluereq(lvl))
2441 op = geniCodeRValue (op, TRUE);
2443 setOperandType (op, rtype);
2448 /*-----------------------------------------------------------------*/
2449 /* geniCodeUnaryMinus - does a unary minus of the operand */
2450 /*-----------------------------------------------------------------*/
2452 geniCodeUnaryMinus (operand * op)
2455 sym_link *optype = operandType (op);
2457 if (IS_LITERAL (optype))
2458 return operandFromLit (-floatFromVal (op->operand.valOperand));
2460 ic = newiCode (UNARYMINUS, op, NULL);
2461 IC_RESULT (ic) = newiTempOperand (optype, 0);
2463 return IC_RESULT (ic);
2466 /*-----------------------------------------------------------------*/
2467 /* geniCodeLeftShift - gen i code for left shift */
2468 /*-----------------------------------------------------------------*/
2470 geniCodeLeftShift (operand * left, operand * right)
2474 ic = newiCode (LEFT_OP, left, right);
2475 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2477 return IC_RESULT (ic);
2480 /*-----------------------------------------------------------------*/
2481 /* geniCodeRightShift - gen i code for right shift */
2482 /*-----------------------------------------------------------------*/
2484 geniCodeRightShift (operand * left, operand * right)
2488 ic = newiCode (RIGHT_OP, left, right);
2489 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2491 return IC_RESULT (ic);
2494 /*-----------------------------------------------------------------*/
2495 /* geniCodeLogic- logic code */
2496 /*-----------------------------------------------------------------*/
2498 geniCodeLogic (operand * left, operand * right, int op)
2502 sym_link *rtype = operandType (right);
2503 sym_link *ltype = operandType (left);
2505 /* left is integral type and right is literal then
2506 check if the literal value is within bounds */
2507 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2509 checkConstantRange(ltype,
2510 operandLitValue(right), "compare operation", 1);
2513 ctype = usualBinaryConversions (&left, &right);
2515 ic = newiCode (op, left, right);
2516 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2518 /* if comparing float
2519 and not a '==' || '!=' || '&&' || '||' (these
2521 if (IS_FLOAT(ctype) &&
2529 return IC_RESULT (ic);
2532 /*-----------------------------------------------------------------*/
2533 /* geniCodeUnary - for a a generic unary operation */
2534 /*-----------------------------------------------------------------*/
2536 geniCodeUnary (operand * op, int oper)
2538 iCode *ic = newiCode (oper, op, NULL);
2540 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2542 return IC_RESULT (ic);
2545 /*-----------------------------------------------------------------*/
2546 /* geniCodeConditional - geniCode for '?' ':' operation */
2547 /*-----------------------------------------------------------------*/
2549 geniCodeConditional (ast * tree,int lvl)
2552 symbol *falseLabel = newiTempLabel (NULL);
2553 symbol *exitLabel = newiTempLabel (NULL);
2554 operand *cond = ast2iCode (tree->left,lvl+1);
2555 operand *true, *false, *result;
2557 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2561 true = ast2iCode (tree->right->left,lvl+1);
2563 /* move the value to a new Operand */
2564 result = newiTempOperand (operandType (true), 0);
2565 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2567 /* generate an unconditional goto */
2568 geniCodeGoto (exitLabel);
2570 /* now for the right side */
2571 geniCodeLabel (falseLabel);
2573 false = ast2iCode (tree->right->right,lvl+1);
2574 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2576 /* create the exit label */
2577 geniCodeLabel (exitLabel);
2582 /*-----------------------------------------------------------------*/
2583 /* geniCodeAssign - generate code for assignment */
2584 /*-----------------------------------------------------------------*/
2586 geniCodeAssign (operand * left, operand * right, int nosupdate)
2589 sym_link *ltype = operandType (left);
2590 sym_link *rtype = operandType (right);
2592 if (!left->isaddr && !IS_ITEMP (left))
2594 werror (E_LVALUE_REQUIRED, "assignment");
2598 /* left is integral type and right is literal then
2599 check if the literal value is within bounds */
2600 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2602 checkConstantRange(ltype,
2603 operandLitValue(right), "= operation", 0);
2606 /* if the left & right type don't exactly match */
2607 /* if pointer set then make sure the check is
2608 done with the type & not the pointer */
2609 /* then cast rights type to left */
2611 /* first check the type for pointer assignement */
2612 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2613 compareType (ltype, rtype) < 0)
2615 if (compareType (ltype->next, rtype) < 0)
2616 right = geniCodeCast (ltype->next, right, TRUE);
2618 else if (compareType (ltype, rtype) < 0)
2619 right = geniCodeCast (ltype, right, TRUE);
2621 /* if left is a true symbol & ! volatile
2622 create an assignment to temporary for
2623 the right & then assign this temporary
2624 to the symbol this is SSA . isn't it simple
2625 and folks have published mountains of paper on it */
2626 if (IS_TRUE_SYMOP (left) &&
2627 !isOperandVolatile (left, FALSE) &&
2628 isOperandGlobal (left))
2632 if (IS_TRUE_SYMOP (right))
2633 sym = OP_SYMBOL (right);
2634 ic = newiCode ('=', NULL, right);
2635 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2636 SPIL_LOC (right) = sym;
2640 ic = newiCode ('=', NULL, right);
2641 IC_RESULT (ic) = left;
2644 /* if left isgptr flag is set then support
2645 routine will be required */
2649 ic->nosupdate = nosupdate;
2653 /*-----------------------------------------------------------------*/
2654 /* geniCodeSEParms - generate code for side effecting fcalls */
2655 /*-----------------------------------------------------------------*/
2657 geniCodeSEParms (ast * parms,int lvl)
2662 if (parms->type == EX_OP && parms->opval.op == PARAM)
2664 geniCodeSEParms (parms->left,lvl);
2665 geniCodeSEParms (parms->right,lvl);
2669 /* hack don't like this but too lazy to think of
2671 if (IS_ADDRESS_OF_OP (parms))
2672 parms->left->lvalue = 1;
2674 if (IS_CAST_OP (parms) &&
2675 IS_PTR (parms->ftype) &&
2676 IS_ADDRESS_OF_OP (parms->right))
2677 parms->right->left->lvalue = 1;
2679 parms->opval.oprnd =
2680 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2682 parms->type = EX_OPERAND;
2685 /*-----------------------------------------------------------------*/
2686 /* geniCodeParms - generates parameters */
2687 /*-----------------------------------------------------------------*/
2689 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2697 /* if this is a param node then do the left & right */
2698 if (parms->type == EX_OP && parms->opval.op == PARAM)
2700 geniCodeParms (parms->left, stack, fetype, func,lvl);
2701 geniCodeParms (parms->right, stack, fetype, func,lvl);
2705 /* get the parameter value */
2706 if (parms->type == EX_OPERAND)
2707 pval = parms->opval.oprnd;
2710 /* maybe this else should go away ?? */
2711 /* hack don't like this but too lazy to think of
2713 if (IS_ADDRESS_OF_OP (parms))
2714 parms->left->lvalue = 1;
2716 if (IS_CAST_OP (parms) &&
2717 IS_PTR (parms->ftype) &&
2718 IS_ADDRESS_OF_OP (parms->right))
2719 parms->right->left->lvalue = 1;
2721 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2724 /* if register parm then make it a send */
2725 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2726 IS_REGPARM (parms->etype)) && !func->hasVargs)
2728 ic = newiCode (SEND, pval, NULL);
2733 /* now decide whether to push or assign */
2734 if (!(options.stackAuto || IS_RENT (fetype)))
2738 operand *top = operandFromSymbol (parms->argSym);
2739 geniCodeAssign (top, pval, 1);
2743 sym_link *p = operandType (pval);
2745 ic = newiCode (IPUSH, pval, NULL);
2747 /* update the stack adjustment */
2748 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2755 /*-----------------------------------------------------------------*/
2756 /* geniCodeCall - generates temp code for calling */
2757 /*-----------------------------------------------------------------*/
2759 geniCodeCall (operand * left, ast * parms,int lvl)
2763 sym_link *type, *etype;
2766 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2767 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2768 werror (E_FUNCTION_EXPECTED);
2772 /* take care of parameters with side-effecting
2773 function calls in them, this is required to take care
2774 of overlaying function parameters */
2775 geniCodeSEParms (parms,lvl);
2777 /* first the parameters */
2778 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2780 /* now call : if symbol then pcall */
2781 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2782 ic = newiCode (PCALL, left, NULL);
2784 ic = newiCode (CALL, left, NULL);
2786 IC_ARGS (ic) = left->operand.symOperand->args;
2787 type = copyLinkChain (operandType (left)->next);
2788 etype = getSpec (type);
2789 SPEC_EXTR (etype) = 0;
2790 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2794 /* stack adjustment after call */
2795 ic->parmBytes = stack;
2800 /*-----------------------------------------------------------------*/
2801 /* geniCodeReceive - generate intermediate code for "receive" */
2802 /*-----------------------------------------------------------------*/
2804 geniCodeReceive (value * args)
2806 /* for all arguments that are passed in registers */
2810 if (IS_REGPARM (args->etype))
2812 operand *opr = operandFromValue (args);
2814 symbol *sym = OP_SYMBOL (opr);
2817 /* we will use it after all optimizations
2818 and before liveRange calculation */
2819 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2822 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2823 options.stackAuto == 0 &&
2824 /* !TARGET_IS_DS390) */
2825 (!(options.model == MODEL_FLAT24)) )
2830 opl = newiTempOperand (args->type, 0);
2832 sym->reqv->key = sym->key;
2833 OP_SYMBOL (sym->reqv)->key = sym->key;
2834 OP_SYMBOL (sym->reqv)->isreqv = 1;
2835 OP_SYMBOL (sym->reqv)->islocal = 0;
2836 SPIL_LOC (sym->reqv) = sym;
2840 ic = newiCode (RECEIVE, NULL, NULL);
2841 currFunc->recvSize = getSize (sym->etype);
2842 IC_RESULT (ic) = opr;
2850 /*-----------------------------------------------------------------*/
2851 /* geniCodeFunctionBody - create the function body */
2852 /*-----------------------------------------------------------------*/
2854 geniCodeFunctionBody (ast * tree,int lvl)
2861 /* reset the auto generation */
2867 func = ast2iCode (tree->left,lvl+1);
2868 fetype = getSpec (operandType (func));
2870 savelineno = lineno;
2871 lineno = OP_SYMBOL (func)->lineDef;
2872 /* create an entry label */
2873 geniCodeLabel (entryLabel);
2874 lineno = savelineno;
2876 /* create a proc icode */
2877 ic = newiCode (FUNCTION, func, NULL);
2878 /* if the function has parmas then */
2879 /* save the parameters information */
2880 ic->argLabel.args = tree->values.args;
2881 ic->lineno = OP_SYMBOL (func)->lineDef;
2885 /* for all parameters that are passed
2886 on registers add a "receive" */
2887 geniCodeReceive (tree->values.args);
2889 /* generate code for the body */
2890 ast2iCode (tree->right,lvl+1);
2892 /* create a label for return */
2893 geniCodeLabel (returnLabel);
2895 /* now generate the end proc */
2896 ic = newiCode (ENDFUNCTION, func, NULL);
2901 /*-----------------------------------------------------------------*/
2902 /* geniCodeReturn - gen icode for 'return' statement */
2903 /*-----------------------------------------------------------------*/
2905 geniCodeReturn (operand * op)
2909 /* if the operand is present force an rvalue */
2911 op = geniCodeRValue (op, FALSE);
2913 ic = newiCode (RETURN, op, NULL);
2917 /*-----------------------------------------------------------------*/
2918 /* geniCodeIfx - generates code for extended if statement */
2919 /*-----------------------------------------------------------------*/
2921 geniCodeIfx (ast * tree,int lvl)
2924 operand *condition = ast2iCode (tree->left,lvl+1);
2927 /* if condition is null then exit */
2931 condition = geniCodeRValue (condition, FALSE);
2933 cetype = getSpec (operandType (condition));
2934 /* if the condition is a literal */
2935 if (IS_LITERAL (cetype))
2937 if (floatFromVal (condition->operand.valOperand))
2939 if (tree->trueLabel)
2940 geniCodeGoto (tree->trueLabel);
2946 if (tree->falseLabel)
2947 geniCodeGoto (tree->falseLabel);
2954 if (tree->trueLabel)
2956 ic = newiCodeCondition (condition,
2961 if (tree->falseLabel)
2962 geniCodeGoto (tree->falseLabel);
2966 ic = newiCodeCondition (condition,
2973 ast2iCode (tree->right,lvl+1);
2976 /*-----------------------------------------------------------------*/
2977 /* geniCodeJumpTable - tries to create a jump table for switch */
2978 /*-----------------------------------------------------------------*/
2980 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2982 int min = 0, max = 0, t, cnt = 0;
2989 if (!tree || !caseVals)
2992 /* the criteria for creating a jump table is */
2993 /* all integer numbers between the maximum & minimum must */
2994 /* be present , the maximum value should not exceed 255 */
2995 min = max = (int) floatFromVal (vch = caseVals);
2996 sprintf (buffer, "_case_%d_%d",
2997 tree->values.switchVals.swNum,
2999 addSet (&labels, newiTempLabel (buffer));
3001 /* if there is only one case value then no need */
3002 if (!(vch = vch->next))
3007 if (((t = (int) floatFromVal (vch)) - max) != 1)
3009 sprintf (buffer, "_case_%d_%d",
3010 tree->values.switchVals.swNum,
3012 addSet (&labels, newiTempLabel (buffer));
3018 /* if the number of case statements <= 2 then */
3019 /* it is not economical to create the jump table */
3020 /* since two compares are needed for boundary conditions */
3021 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3024 if (tree->values.switchVals.swDefault)
3025 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3027 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3029 falseLabel = newiTempLabel (buffer);
3031 /* so we can create a jumptable */
3032 /* first we rule out the boundary conditions */
3033 /* if only optimization says so */
3034 if (!optimize.noJTabBoundary)
3036 sym_link *cetype = getSpec (operandType (cond));
3037 /* no need to check the lower bound if
3038 the condition is unsigned & minimum value is zero */
3039 if (!(min == 0 && SPEC_USIGN (cetype)))
3041 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3042 ic = newiCodeCondition (boundary, falseLabel, NULL);
3046 /* now for upper bounds */
3047 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3048 ic = newiCodeCondition (boundary, falseLabel, NULL);
3052 /* if the min is not zero then we no make it zero */
3055 cond = geniCodeSubtract (cond, operandFromLit (min));
3056 setOperandType (cond, UCHARTYPE);
3059 /* now create the jumptable */
3060 ic = newiCode (JUMPTABLE, NULL, NULL);
3061 IC_JTCOND (ic) = cond;
3062 IC_JTLABELS (ic) = labels;
3067 /*-----------------------------------------------------------------*/
3068 /* geniCodeSwitch - changes a switch to a if statement */
3069 /*-----------------------------------------------------------------*/
3071 geniCodeSwitch (ast * tree,int lvl)
3074 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3075 value *caseVals = tree->values.switchVals.swVals;
3076 symbol *trueLabel, *falseLabel;
3078 /* if we can make this a jump table */
3079 if (geniCodeJumpTable (cond, caseVals, tree))
3080 goto jumpTable; /* no need for the comparison */
3082 /* for the cases defined do */
3086 operand *compare = geniCodeLogic (cond,
3087 operandFromValue (caseVals),
3090 sprintf (buffer, "_case_%d_%d",
3091 tree->values.switchVals.swNum,
3092 (int) floatFromVal (caseVals));
3093 trueLabel = newiTempLabel (buffer);
3095 ic = newiCodeCondition (compare, trueLabel, NULL);
3097 caseVals = caseVals->next;
3102 /* if default is present then goto break else break */
3103 if (tree->values.switchVals.swDefault)
3104 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3106 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3108 falseLabel = newiTempLabel (buffer);
3109 geniCodeGoto (falseLabel);
3112 ast2iCode (tree->right,lvl+1);
3115 /*-----------------------------------------------------------------*/
3116 /* geniCodeInline - intermediate code for inline assembler */
3117 /*-----------------------------------------------------------------*/
3119 geniCodeInline (ast * tree)
3123 ic = newiCode (INLINEASM, NULL, NULL);
3124 IC_INLINE (ic) = tree->values.inlineasm;
3128 /*-----------------------------------------------------------------*/
3129 /* geniCodeArrayInit - intermediate code for array initializer */
3130 /*-----------------------------------------------------------------*/
3132 geniCodeArrayInit (ast * tree, operand *array)
3136 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3137 ic = newiCode (ARRAYINIT, array, NULL);
3138 IC_ARRAYILIST (ic) = tree->values.constlist;
3140 operand *left=newOperand(), *right=newOperand();
3141 left->type=right->type=SYMBOL;
3142 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3143 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3144 ic = newiCode (ARRAYINIT, left, right);
3149 /*-----------------------------------------------------------------*/
3150 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3151 /* particular case. Ie : assigning or dereferencing array or ptr */
3152 /*-----------------------------------------------------------------*/
3153 set * lvaluereqSet = NULL;
3154 typedef struct lvalItem
3161 /*-----------------------------------------------------------------*/
3162 /* addLvaluereq - add a flag for lvalreq for current ast level */
3163 /*-----------------------------------------------------------------*/
3164 void addLvaluereq(int lvl)
3166 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3169 addSetHead(&lvaluereqSet,lpItem);
3172 /*-----------------------------------------------------------------*/
3173 /* delLvaluereq - del a flag for lvalreq for current ast level */
3174 /*-----------------------------------------------------------------*/
3178 lpItem = getSet(&lvaluereqSet);
3179 if(lpItem) free(lpItem);
3181 /*-----------------------------------------------------------------*/
3182 /* clearLvaluereq - clear lvalreq flag */
3183 /*-----------------------------------------------------------------*/
3184 void clearLvaluereq()
3187 lpItem = peekSet(lvaluereqSet);
3188 if(lpItem) lpItem->req = 0;
3190 /*-----------------------------------------------------------------*/
3191 /* getLvaluereq - get the last lvalreq level */
3192 /*-----------------------------------------------------------------*/
3193 int getLvaluereqLvl()
3196 lpItem = peekSet(lvaluereqSet);
3197 if(lpItem) return lpItem->lvl;
3200 /*-----------------------------------------------------------------*/
3201 /* isLvaluereq - is lvalreq valid for this level ? */
3202 /*-----------------------------------------------------------------*/
3203 int isLvaluereq(int lvl)
3206 lpItem = peekSet(lvaluereqSet);
3207 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3211 /*-----------------------------------------------------------------*/
3212 /* ast2iCode - creates an icodeList from an ast */
3213 /*-----------------------------------------------------------------*/
3215 ast2iCode (ast * tree,int lvl)
3217 operand *left = NULL;
3218 operand *right = NULL;
3221 /* set the global variables for filename & line number */
3223 filename = tree->filename;
3225 lineno = tree->lineno;
3227 block = tree->block;
3229 scopeLevel = tree->level;
3231 if (tree->type == EX_VALUE)
3232 return operandFromValue (tree->opval.val);
3234 if (tree->type == EX_LINK)
3235 return operandFromLink (tree->opval.lnk);
3237 /* if we find a nullop */
3238 if (tree->type == EX_OP &&
3239 (tree->opval.op == NULLOP ||
3240 tree->opval.op == BLOCK))
3242 ast2iCode (tree->left,lvl+1);
3243 ast2iCode (tree->right,lvl+1);
3247 /* special cases for not evaluating */
3248 if (tree->opval.op != ':' &&
3249 tree->opval.op != '?' &&
3250 tree->opval.op != CALL &&
3251 tree->opval.op != IFX &&
3252 tree->opval.op != LABEL &&
3253 tree->opval.op != GOTO &&
3254 tree->opval.op != SWITCH &&
3255 tree->opval.op != FUNCTION &&
3256 tree->opval.op != INLINEASM)
3259 if (IS_ASSIGN_OP (tree->opval.op) ||
3260 IS_DEREF_OP (tree) ||
3261 (tree->opval.op == '&' && !tree->right) ||
3262 tree->opval.op == PTR_OP)
3265 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3266 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3269 left = operandFromAst (tree->left,lvl);
3271 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3272 left = geniCodeRValue (left, TRUE);
3276 left = operandFromAst (tree->left,lvl);
3278 if (tree->opval.op == INC_OP ||
3279 tree->opval.op == DEC_OP)
3282 right = operandFromAst (tree->right,lvl);
3287 right = operandFromAst (tree->right,lvl);
3291 /* now depending on the type of operand */
3292 /* this will be a biggy */
3293 switch (tree->opval.op)
3296 case '[': /* array operation */
3298 //sym_link *ltype = operandType (left);
3299 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3300 left = geniCodeRValue (left, FALSE);
3301 right = geniCodeRValue (right, TRUE);
3304 return geniCodeArray (left, right,lvl);
3306 case '.': /* structure dereference */
3307 if (IS_PTR (operandType (left)))
3308 left = geniCodeRValue (left, TRUE);
3310 left = geniCodeRValue (left, FALSE);
3312 return geniCodeStruct (left, right, tree->lvalue);
3314 case PTR_OP: /* structure pointer dereference */
3317 pType = operandType (left);
3318 left = geniCodeRValue (left, TRUE);
3320 setOClass (pType, getSpec (operandType (left)));
3323 return geniCodeStruct (left, right, tree->lvalue);
3325 case INC_OP: /* increment operator */
3327 return geniCodePostInc (left);
3329 return geniCodePreInc (right);
3331 case DEC_OP: /* decrement operator */
3333 return geniCodePostDec (left);
3335 return geniCodePreDec (right);
3337 case '&': /* bitwise and or address of operator */
3339 { /* this is a bitwise operator */
3340 left = geniCodeRValue (left, FALSE);
3341 right = geniCodeRValue (right, FALSE);
3342 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3345 return geniCodeAddressOf (left);
3347 case '|': /* bitwise or & xor */
3349 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3350 geniCodeRValue (right, FALSE),
3355 return geniCodeDivision (geniCodeRValue (left, FALSE),
3356 geniCodeRValue (right, FALSE));
3359 return geniCodeModulus (geniCodeRValue (left, FALSE),
3360 geniCodeRValue (right, FALSE));
3363 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3364 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3366 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3370 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3371 geniCodeRValue (right, FALSE));
3373 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3377 return geniCodeAdd (geniCodeRValue (left, FALSE),
3378 geniCodeRValue (right, FALSE),lvl);
3380 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3383 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3384 geniCodeRValue (right, FALSE));
3387 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3388 geniCodeRValue (right, FALSE));
3390 return geniCodeCast (operandType (left),
3391 geniCodeRValue (right, FALSE), FALSE);
3397 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3401 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3402 setOperandType (op, UCHARTYPE);
3413 return geniCodeLogic (geniCodeRValue (left, FALSE),
3414 geniCodeRValue (right, FALSE),
3417 return geniCodeConditional (tree,lvl);
3420 return operandFromLit (getSize (tree->right->ftype));
3424 sym_link *rtype = operandType (right);
3425 sym_link *ltype = operandType (left);
3426 if (IS_PTR (rtype) && IS_ITEMP (right)
3427 && right->isaddr && compareType (rtype->next, ltype) == 1)
3428 right = geniCodeRValue (right, TRUE);
3430 right = geniCodeRValue (right, FALSE);
3432 geniCodeAssign (left, right, 0);
3437 geniCodeAssign (left,
3438 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3440 geniCodeRValue (right, FALSE),FALSE), 0);
3444 geniCodeAssign (left,
3445 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3447 geniCodeRValue (right, FALSE)), 0);
3450 geniCodeAssign (left,
3451 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3453 geniCodeRValue (right, FALSE)), 0);
3456 sym_link *rtype = operandType (right);
3457 sym_link *ltype = operandType (left);
3458 if (IS_PTR (rtype) && IS_ITEMP (right)
3459 && right->isaddr && compareType (rtype->next, ltype) == 1)
3460 right = geniCodeRValue (right, TRUE);
3462 right = geniCodeRValue (right, FALSE);
3465 return geniCodeAssign (left,
3466 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3472 sym_link *rtype = operandType (right);
3473 sym_link *ltype = operandType (left);
3474 if (IS_PTR (rtype) && IS_ITEMP (right)
3475 && right->isaddr && compareType (rtype->next, ltype) == 1)
3477 right = geniCodeRValue (right, TRUE);
3481 right = geniCodeRValue (right, FALSE);
3484 geniCodeAssign (left,
3485 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3491 geniCodeAssign (left,
3492 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3494 geniCodeRValue (right, FALSE)), 0);
3497 geniCodeAssign (left,
3498 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3500 geniCodeRValue (right, FALSE)), 0);
3503 geniCodeAssign (left,
3504 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3506 geniCodeRValue (right, FALSE),
3508 operandType (left)), 0);
3511 geniCodeAssign (left,
3512 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3514 geniCodeRValue (right, FALSE),
3516 operandType (left)), 0);
3519 geniCodeAssign (left,
3520 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3522 geniCodeRValue (right, FALSE),
3524 operandType (left)), 0);
3526 return geniCodeRValue (right, FALSE);
3529 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3532 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3533 return ast2iCode (tree->right,lvl+1);
3536 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3537 return ast2iCode (tree->right,lvl+1);
3540 geniCodeFunctionBody (tree,lvl);
3544 geniCodeReturn (right);
3548 geniCodeIfx (tree,lvl);
3552 geniCodeSwitch (tree,lvl);
3556 geniCodeInline (tree);
3560 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3567 /*-----------------------------------------------------------------*/
3568 /* reverseICChain - gets from the list and creates a linkedlist */
3569 /*-----------------------------------------------------------------*/
3576 while ((loop = getSet (&iCodeChain)))
3588 /*-----------------------------------------------------------------*/
3589 /* iCodeFromAst - given an ast will convert it to iCode */
3590 /*-----------------------------------------------------------------*/
3592 iCodeFromAst (ast * tree)
3594 returnLabel = newiTempLabel ("_return");
3595 entryLabel = newiTempLabel ("_entry");
3597 return reverseiCChain ();