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 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
42 symbol *returnLabel; /* function return label */
43 symbol *entryLabel; /* function entry label */
45 /*-----------------------------------------------------------------*/
46 /* forward definition of some functions */
47 operand *geniCodeDivision (operand *, operand *);
48 operand *geniCodeAssign (operand *, operand *, int);
49 operand *geniCodeArray (operand *, operand *,int);
50 operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
55 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
56 /* forward definition of ic print functions */
57 PRINTFUNC (picGetValueAtAddr);
58 PRINTFUNC (picSetValueAtAddr);
59 PRINTFUNC (picAddrOf);
60 PRINTFUNC (picGeneric);
61 PRINTFUNC (picGenericOne);
63 PRINTFUNC (picAssign);
67 PRINTFUNC (picJumpTable);
68 PRINTFUNC (picInline);
69 PRINTFUNC (picReceive);
71 iCodeTable codeTable[] =
73 {'!', "not", picGenericOne, NULL},
74 {'~', "~", picGenericOne, NULL},
75 {RRC, "rrc", picGenericOne, NULL},
76 {RLC, "rlc", picGenericOne, NULL},
77 {GETHBIT, "ghbit", picGenericOne, NULL},
78 {UNARYMINUS, "-", picGenericOne, NULL},
79 {IPUSH, "push", picGenericOne, NULL},
80 {IPOP, "pop", picGenericOne, NULL},
81 {CALL, "call", picGenericOne, NULL},
82 {PCALL, "pcall", picGenericOne, NULL},
83 {FUNCTION, "proc", picGenericOne, NULL},
84 {ENDFUNCTION, "eproc", picGenericOne, NULL},
85 {RETURN, "ret", picGenericOne, NULL},
86 {'+', "+", picGeneric, NULL},
87 {'-', "-", picGeneric, NULL},
88 {'*', "*", picGeneric, NULL},
89 {'/', "/", picGeneric, NULL},
90 {'%', "%", picGeneric, NULL},
91 {'>', ">", picGeneric, NULL},
92 {'<', "<", picGeneric, NULL},
93 {LE_OP, "<=", picGeneric, NULL},
94 {GE_OP, ">=", picGeneric, NULL},
95 {EQ_OP, "==", picGeneric, NULL},
96 {NE_OP, "!=", picGeneric, NULL},
97 {AND_OP, "&&", picGeneric, NULL},
98 {OR_OP, "||", picGeneric, NULL},
99 {'^', "^", picGeneric, NULL},
100 {'|', "|", picGeneric, NULL},
101 {BITWISEAND, "&", picGeneric, NULL},
102 {LEFT_OP, "<<", picGeneric, NULL},
103 {RIGHT_OP, ">>", picGeneric, NULL},
104 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
105 {ADDRESS_OF, "&", picAddrOf, NULL},
106 {CAST, "<>", picCast, NULL},
107 {'=', ":=", picAssign, NULL},
108 {LABEL, "", picLabel, NULL},
109 {GOTO, "", picGoto, NULL},
110 {JUMPTABLE, "jtab", picJumpTable, NULL},
111 {IFX, "if", picIfx, NULL},
112 {INLINEASM, "", picInline, NULL},
113 {RECEIVE, "recv", picReceive, NULL},
114 {SEND, "send", picGenericOne, NULL},
115 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
118 /*-----------------------------------------------------------------*/
119 /* checkConstantRange: check a constant against the type */
120 /*-----------------------------------------------------------------*/
122 /* pedantic=0: allmost anything is allowed as long as the absolute
123 value is within the bit range of the type, and -1 is treated as
124 0xf..f for unsigned types (e.g. in assign)
125 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
126 pedantic>1: "char c=200" is not allowed (evaluates to -56)
129 void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
131 char message[132]="";
136 max = pow ((double)2.0, (double)bitsForType(ltype));
138 if (SPEC_LONG(val->type)) {
139 v=SPEC_CVAL(val->type).v_long;
141 v=SPEC_CVAL(val->type).v_int;
146 // this could be a good idea
147 if (options.pedantic)
151 if (SPEC_NOUN(ltype)==FLOAT) {
156 if (!SPEC_USIGN(val->type) && v<0) {
158 if (SPEC_USIGN(ltype) && (pedantic>1)) {
164 // if very pedantic: "char c=200" is not allowed
165 if (pedantic>1 && !SPEC_USIGN(ltype)) {
166 max = max/2 + negative;
174 sprintf (message, "for %s %s in %s",
175 SPEC_USIGN(ltype) ? "unsigned" : "signed",
176 nounName(ltype), msg);
177 werror (W_CONST_RANGE, message);
184 /*-----------------------------------------------------------------*/
185 /* operandName - returns the name of the operand */
186 /*-----------------------------------------------------------------*/
188 printOperand (operand * op, FILE * file)
205 opetype = getSpec (operandType (op));
206 if (SPEC_NOUN (opetype) == V_FLOAT)
207 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
209 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
210 printTypeChain (operandType (op), file);
217 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}" , */
218 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
220 OP_LIVEFROM (op), OP_LIVETO (op),
221 OP_SYMBOL (op)->stack,
222 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
226 printTypeChain (operandType (op), file);
227 if (SPIL_LOC (op) && IS_ITEMP (op))
228 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
233 /* if assigned to registers */
234 if (OP_SYMBOL (op)->nRegs)
236 if (OP_SYMBOL (op)->isspilt)
238 if (!OP_SYMBOL (op)->remat)
239 if (OP_SYMBOL (op)->usl.spillLoc)
240 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
241 OP_SYMBOL (op)->usl.spillLoc->rname :
242 OP_SYMBOL (op)->usl.spillLoc->name));
244 fprintf (file, "[err]");
246 fprintf (file, "[remat]");
252 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
253 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
258 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
259 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
260 /* if assigned to registers */
261 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
265 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
266 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
267 OP_SYMBOL (op)->regs[i]->name :
276 printTypeChain (op->operand.typeOperand, file);
282 fprintf (file, "\n");
287 /*-----------------------------------------------------------------*/
288 /* print functions */
289 /*-----------------------------------------------------------------*/
290 PRINTFUNC (picGetValueAtAddr)
293 printOperand (IC_RESULT (ic), of);
296 printOperand (IC_LEFT (ic), of);
302 PRINTFUNC (picSetValueAtAddr)
306 printOperand (IC_LEFT (ic), of);
307 fprintf (of, "] = ");
308 printOperand (IC_RIGHT (ic), of);
312 PRINTFUNC (picAddrOf)
315 printOperand (IC_RESULT (ic), of);
316 if (IS_ITEMP (IC_LEFT (ic)))
319 fprintf (of, " = &[");
320 printOperand (IC_LEFT (ic), of);
323 if (IS_ITEMP (IC_LEFT (ic)))
324 fprintf (of, " offsetAdd ");
327 printOperand (IC_RIGHT (ic), of);
329 if (IS_ITEMP (IC_LEFT (ic)))
335 PRINTFUNC (picJumpTable)
340 fprintf (of, "%s\t", s);
341 printOperand (IC_JTCOND (ic), of);
343 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
344 sym = setNextItem (IC_JTLABELS (ic)))
345 fprintf (of, "\t\t\t%s\n", sym->name);
348 PRINTFUNC (picGeneric)
351 printOperand (IC_RESULT (ic), of);
353 printOperand (IC_LEFT (ic), of);
354 fprintf (of, " %s ", s);
355 printOperand (IC_RIGHT (ic), of);
359 PRINTFUNC (picGenericOne)
364 printOperand (IC_RESULT (ic), of);
370 fprintf (of, "%s ", s);
371 printOperand (IC_LEFT (ic), of);
374 if (!IC_RESULT (ic) && !IC_LEFT (ic))
383 printOperand (IC_RESULT (ic), of);
385 printOperand (IC_LEFT (ic), of);
386 printOperand (IC_RIGHT (ic), of);
391 PRINTFUNC (picAssign)
395 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
398 printOperand (IC_RESULT (ic), of);
400 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
403 fprintf (of, " %s ", s);
404 printOperand (IC_RIGHT (ic), of);
411 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
417 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
424 printOperand (IC_COND (ic), of);
427 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
430 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
432 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
436 PRINTFUNC (picInline)
438 fprintf (of, "%s", IC_INLINE (ic));
441 PRINTFUNC (picReceive)
443 printOperand (IC_RESULT (ic), of);
444 fprintf (of, " = %s ", s);
445 printOperand (IC_LEFT (ic), of);
449 /*-----------------------------------------------------------------*/
450 /* piCode - prints one iCode */
451 /*-----------------------------------------------------------------*/
453 piCode (void *item, FILE * of)
461 icTab = getTableEntry (ic->op);
462 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
463 ic->filename, ic->lineno,
464 ic->seq, ic->key, ic->depth, ic->supportRtn);
465 icTab->iCodePrint (of, ic, icTab->printName);
471 printiCChain(ic,stdout);
473 /*-----------------------------------------------------------------*/
474 /* printiCChain - prints intermediate code for humans */
475 /*-----------------------------------------------------------------*/
477 printiCChain (iCode * icChain, FILE * of)
484 for (loop = icChain; loop; loop = loop->next)
486 if ((icTab = getTableEntry (loop->op)))
488 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
489 loop->filename, loop->lineno,
490 loop->seq, loop->key, loop->depth, loop->supportRtn);
492 icTab->iCodePrint (of, loop, icTab->printName);
498 /*-----------------------------------------------------------------*/
499 /* newOperand - allocate, init & return a new iCode */
500 /*-----------------------------------------------------------------*/
506 op = Safe_alloc ( sizeof (operand));
512 /*-----------------------------------------------------------------*/
513 /* newiCode - create and return a new iCode entry initialised */
514 /*-----------------------------------------------------------------*/
516 newiCode (int op, operand * left, operand * right)
520 ic = Safe_alloc ( sizeof (iCode));
523 ic->filename = filename;
525 ic->level = scopeLevel;
527 ic->key = iCodeKey++;
529 IC_RIGHT (ic) = right;
534 /*-----------------------------------------------------------------*/
535 /* newiCode for conditional statements */
536 /*-----------------------------------------------------------------*/
538 newiCodeCondition (operand * condition,
544 if (IS_VOID(OP_SYMBOL(condition)->type)) {
545 werror(E_VOID_VALUE_USED);
548 ic = newiCode (IFX, NULL, NULL);
549 IC_COND (ic) = condition;
550 IC_TRUE (ic) = trueLabel;
551 IC_FALSE (ic) = falseLabel;
555 /*-----------------------------------------------------------------*/
556 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
557 /*-----------------------------------------------------------------*/
559 newiCodeLabelGoto (int op, symbol * label)
563 ic = newiCode (op, NULL, NULL);
565 ic->argLabel.label = label;
567 IC_RIGHT (ic) = NULL;
568 IC_RESULT (ic) = NULL;
572 /*-----------------------------------------------------------------*/
573 /* newiTemp - allocate & return a newItemp Variable */
574 /*-----------------------------------------------------------------*/
581 sprintf (buffer, "%s", s);
583 sprintf (buffer, "iTemp%d", iTempNum++);
584 itmp = newSymbol (buffer, 1);
585 strcpy (itmp->rname, itmp->name);
591 /*-----------------------------------------------------------------*/
592 /* newiTempLabel - creates a temp variable label */
593 /*-----------------------------------------------------------------*/
595 newiTempLabel (char *s)
599 /* check if this alredy exists */
600 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
604 itmplbl = newSymbol (s, 1);
607 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
608 itmplbl = newSymbol (buffer, 1);
613 itmplbl->key = labelKey++;
614 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
618 /*-----------------------------------------------------------------*/
619 /* newiTempPreheaderLabel - creates a new preheader label */
620 /*-----------------------------------------------------------------*/
622 newiTempPreheaderLabel ()
626 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
627 itmplbl = newSymbol (buffer, 1);
631 itmplbl->key = labelKey++;
632 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
637 /*-----------------------------------------------------------------*/
638 /* initiCode - initialises some iCode related stuff */
639 /*-----------------------------------------------------------------*/
646 /*-----------------------------------------------------------------*/
647 /* copyiCode - make a copy of the iCode given */
648 /*-----------------------------------------------------------------*/
650 copyiCode (iCode * ic)
652 iCode *nic = newiCode (ic->op, NULL, NULL);
654 nic->lineno = ic->lineno;
655 nic->filename = ic->filename;
656 nic->block = ic->block;
657 nic->level = ic->level;
658 nic->parmBytes = ic->parmBytes;
660 /* deal with the special cases first */
664 IC_COND (nic) = operandFromOperand (IC_COND (ic));
665 IC_TRUE (nic) = IC_TRUE (ic);
666 IC_FALSE (nic) = IC_FALSE (ic);
670 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
671 IC_JTLABELS (nic) = IC_JTLABELS (ic);
676 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
677 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
678 IC_ARGS (nic) = IC_ARGS (ic);
682 IC_INLINE (nic) = IC_INLINE (ic);
686 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
690 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
691 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
692 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
698 /*-----------------------------------------------------------------*/
699 /* getTableEntry - gets the table entry for the given operator */
700 /*-----------------------------------------------------------------*/
702 getTableEntry (int oper)
706 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
707 if (oper == codeTable[i].icode)
708 return &codeTable[i];
713 /*-----------------------------------------------------------------*/
714 /* newiTempOperand - new intermediate temp operand */
715 /*-----------------------------------------------------------------*/
717 newiTempOperand (sym_link * type, char throwType)
720 operand *op = newOperand ();
724 itmp = newiTemp (NULL);
726 etype = getSpec (type);
728 if (IS_LITERAL (etype))
731 /* copy the type information */
733 itmp->etype = getSpec (itmp->type = (throwType ? type :
734 copyLinkChain (type)));
735 if (IS_LITERAL (itmp->etype))
737 SPEC_SCLS (itmp->etype) = S_REGISTER;
738 SPEC_OCLS (itmp->etype) = reg;
741 op->operand.symOperand = itmp;
742 op->key = itmp->key = ++operandKey;
746 /*-----------------------------------------------------------------*/
747 /* operandType - returns the type chain for an operand */
748 /*-----------------------------------------------------------------*/
750 operandType (operand * op)
752 /* depending on type of operand */
757 return op->operand.valOperand->type;
760 return op->operand.symOperand->type;
763 return op->operand.typeOperand;
765 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
766 " operand type not known ");
767 assert (0); /* should never come here */
768 /* Just to keep the compiler happy */
769 return (sym_link *) 0;
773 /*-----------------------------------------------------------------*/
774 /* isParamterToCall - will return 1 if op is a parameter to args */
775 /*-----------------------------------------------------------------*/
777 isParameterToCall (value * args, operand * op)
784 isSymbolEqual (op->operand.symOperand, tval->sym))
791 /*-----------------------------------------------------------------*/
792 /* isOperandGlobal - return 1 if operand is a global variable */
793 /*-----------------------------------------------------------------*/
795 isOperandGlobal (operand * op)
803 if (op->type == SYMBOL &&
804 (op->operand.symOperand->level == 0 ||
805 IS_STATIC (op->operand.symOperand->etype) ||
806 IS_EXTERN (op->operand.symOperand->etype))
813 /*-----------------------------------------------------------------*/
814 /* isOperandVolatile - return 1 if the operand is volatile */
815 /*-----------------------------------------------------------------*/
817 isOperandVolatile (operand * op, bool chkTemp)
822 if (IS_ITEMP (op) && !chkTemp)
825 opetype = getSpec (optype = operandType (op));
827 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
830 if (IS_VOLATILE (opetype))
835 /*-----------------------------------------------------------------*/
836 /* isOperandLiteral - returns 1 if an operand contains a literal */
837 /*-----------------------------------------------------------------*/
839 isOperandLiteral (operand * op)
846 opetype = getSpec (operandType (op));
848 if (IS_LITERAL (opetype))
853 /*-----------------------------------------------------------------*/
854 /* isOperandInFarSpace - will return true if operand is in farSpace */
855 /*-----------------------------------------------------------------*/
857 isOperandInFarSpace (operand * op)
867 if (!IS_TRUE_SYMOP (op))
870 etype = SPIL_LOC (op)->etype;
876 etype = getSpec (operandType (op));
878 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
881 /*-----------------------------------------------------------------*/
882 /* isOperandOnStack - will return true if operand is on stack */
883 /*-----------------------------------------------------------------*/
885 isOperandOnStack (operand * op)
895 etype = getSpec (operandType (op));
897 return ((IN_STACK (etype)) ? TRUE : FALSE);
900 /*-----------------------------------------------------------------*/
901 /* operandLitValue - literal value of an operand */
902 /*-----------------------------------------------------------------*/
904 operandLitValue (operand * op)
906 assert (isOperandLiteral (op));
908 return floatFromVal (op->operand.valOperand);
911 /*-----------------------------------------------------------------*/
912 /* operandOperation - perforoms operations on operands */
913 /*-----------------------------------------------------------------*/
915 operandOperation (operand * left, operand * right,
916 int op, sym_link * type)
918 sym_link *let , *ret=NULL;
919 operand *retval = (operand *) 0;
921 assert (isOperandLiteral (left));
922 let = getSpec(operandType(left));
924 assert (isOperandLiteral (right));
925 ret = getSpec(operandType(left));
931 // we need this now because of SDCCcse.c:1.52, it's a regression though
935 retval = operandFromValue (valCastLiteral (type,
936 operandLitValue (left) +
937 operandLitValue (right)));
940 retval = operandFromValue (valCastLiteral (type,
941 operandLitValue (left) -
942 operandLitValue (right)));
945 retval = operandFromValue (valCastLiteral (type,
946 operandLitValue (left) *
947 operandLitValue (right)));
950 if ((unsigned long) operandLitValue (right) == 0)
952 werror (E_DIVIDE_BY_ZERO);
957 retval = operandFromValue (valCastLiteral (type,
958 operandLitValue (left) /
959 operandLitValue (right)));
962 if ((unsigned long) operandLitValue (right) == 0) {
963 werror (E_DIVIDE_BY_ZERO);
967 retval = operandFromLit ((SPEC_USIGN(let) ?
968 (unsigned long) operandLitValue (left) :
969 (long) operandLitValue (left)) %
971 (unsigned long) operandLitValue (right) :
972 (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 ((SPEC_USIGN(let) ?
985 (unsigned long) operandLitValue (left) :
986 (long) operandLitValue (left)) >>
988 (unsigned long) operandLitValue (right) :
989 (long) 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 (operandLitValue (left) >
1009 operandLitValue (right));
1012 retval = operandFromLit (operandLitValue (left) >=
1013 operandLitValue (right));
1016 retval = operandFromLit ((long)operandLitValue(left) &
1017 (long)operandLitValue(right));
1020 retval = operandFromLit ((long)operandLitValue (left) |
1021 (long)operandLitValue (right));
1024 retval = operandFromLit ((long)operandLitValue (left) ^
1025 (long)operandLitValue (right));
1028 retval = operandFromLit (operandLitValue (left) &&
1029 operandLitValue (right));
1032 retval = operandFromLit (operandLitValue (left) ||
1033 operandLitValue (right));
1037 long i = (long) operandLitValue (left);
1039 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1045 long i = (long) operandLitValue (left);
1047 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1053 retval = operandFromLit (-1 * operandLitValue (left));
1057 retval = operandFromLit (~((long) operandLitValue (left)));
1061 retval = operandFromLit (!operandLitValue (left));
1065 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1066 " operandOperation invalid operator ");
1074 /*-----------------------------------------------------------------*/
1075 /* isOperandEqual - compares two operand & return 1 if they r = */
1076 /*-----------------------------------------------------------------*/
1078 isOperandEqual (operand * left, operand * right)
1080 /* if the pointers are equal then they are equal */
1084 /* if either of them null then false */
1085 if (!left || !right)
1088 if (left->type != right->type)
1091 if (IS_SYMOP (left) && IS_SYMOP (right))
1092 return left->key == right->key;
1094 /* if types are the same */
1098 return isSymbolEqual (left->operand.symOperand,
1099 right->operand.symOperand);
1101 return (floatFromVal (left->operand.valOperand) ==
1102 floatFromVal (right->operand.valOperand));
1104 if (compareType (left->operand.typeOperand,
1105 right->operand.typeOperand) == 1)
1112 /*-------------------------------------------------------------------*/
1113 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1114 /*-------------------------------------------------------------------*/
1116 isiCodeEqual (iCode * left, iCode * right)
1118 /* if the same pointer */
1122 /* if either of them null */
1123 if (!left || !right)
1126 /* if operand are the same */
1127 if (left->op == right->op)
1130 /* compare all the elements depending on type */
1131 if (left->op != IFX)
1133 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1135 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1141 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1143 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1145 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1154 /*-----------------------------------------------------------------*/
1155 /* newiTempFromOp - create a temp Operand with same attributes */
1156 /*-----------------------------------------------------------------*/
1158 newiTempFromOp (operand * op)
1168 nop = newiTempOperand (operandType (op), TRUE);
1169 nop->isaddr = op->isaddr;
1170 nop->isvolatile = op->isvolatile;
1171 nop->isGlobal = op->isGlobal;
1172 nop->isLiteral = op->isLiteral;
1173 nop->usesDefs = op->usesDefs;
1174 nop->isParm = op->isParm;
1178 /*-----------------------------------------------------------------*/
1179 /* operand from operand - creates an operand holder for the type */
1180 /*-----------------------------------------------------------------*/
1182 operandFromOperand (operand * op)
1188 nop = newOperand ();
1189 nop->type = op->type;
1190 nop->isaddr = op->isaddr;
1192 nop->isvolatile = op->isvolatile;
1193 nop->isGlobal = op->isGlobal;
1194 nop->isLiteral = op->isLiteral;
1195 nop->usesDefs = op->usesDefs;
1196 nop->isParm = op->isParm;
1201 nop->operand.symOperand = op->operand.symOperand;
1204 nop->operand.valOperand = op->operand.valOperand;
1207 nop->operand.typeOperand = op->operand.typeOperand;
1214 /*-----------------------------------------------------------------*/
1215 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1216 /*-----------------------------------------------------------------*/
1218 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1220 operand *nop = operandFromOperand (op);
1222 if (nop->type == SYMBOL)
1224 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1225 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1231 /*-----------------------------------------------------------------*/
1232 /* operandFromSymbol - creates an operand from a symbol */
1233 /*-----------------------------------------------------------------*/
1235 operandFromSymbol (symbol * sym)
1240 /* if the symbol's type is a literal */
1241 /* then it is an enumerator type */
1242 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1243 return operandFromValue (valFromType (sym->etype));
1246 sym->key = ++operandKey;
1248 /* if this an implicit variable, means struct/union */
1249 /* member so just return it */
1250 if (sym->implicit || IS_FUNC (sym->type))
1254 op->operand.symOperand = sym;
1256 op->isvolatile = isOperandVolatile (op, TRUE);
1257 op->isGlobal = isOperandGlobal (op);
1261 /* under the following conditions create a
1262 register equivalent for a local symbol */
1263 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1264 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1265 /* (!TARGET_IS_DS390)) && */
1266 (!(options.model == MODEL_FLAT24)) ) &&
1267 options.stackAuto == 0)
1270 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1271 !IS_FUNC (sym->type) && /* not a function */
1272 !sym->_isparm && /* not a parameter */
1273 sym->level && /* is a local variable */
1274 !sym->addrtaken && /* whose address has not been taken */
1275 !sym->reqv && /* does not already have a register euivalence */
1276 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1277 !IS_STATIC (sym->etype) && /* and not declared static */
1278 !sym->islbl && /* not a label */
1279 ok && /* farspace check */
1280 !IS_BITVAR (sym->etype) /* not a bit variable */
1284 /* we will use it after all optimizations
1285 and before liveRange calculation */
1286 sym->reqv = newiTempOperand (sym->type, 0);
1287 sym->reqv->key = sym->key;
1288 OP_SYMBOL (sym->reqv)->key = sym->key;
1289 OP_SYMBOL (sym->reqv)->isreqv = 1;
1290 OP_SYMBOL (sym->reqv)->islocal = 1;
1291 SPIL_LOC (sym->reqv) = sym;
1294 if (!IS_AGGREGATE (sym->type))
1298 op->operand.symOperand = sym;
1301 op->isvolatile = isOperandVolatile (op, TRUE);
1302 op->isGlobal = isOperandGlobal (op);
1303 op->isPtr = IS_PTR (operandType (op));
1304 op->isParm = sym->_isparm;
1309 /* itemp = &[_symbol] */
1311 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1312 IC_LEFT (ic)->type = SYMBOL;
1313 IC_LEFT (ic)->operand.symOperand = sym;
1314 IC_LEFT (ic)->key = sym->key;
1315 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1316 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1317 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1320 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1321 if (IS_ARRAY (sym->type))
1323 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1324 IC_RESULT (ic)->isaddr = 0;
1327 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1329 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1333 return IC_RESULT (ic);
1336 /*-----------------------------------------------------------------*/
1337 /* operandFromValue - creates an operand from value */
1338 /*-----------------------------------------------------------------*/
1340 operandFromValue (value * val)
1344 /* if this is a symbol then do the symbol thing */
1346 return operandFromSymbol (val->sym);
1348 /* this is not a symbol */
1351 op->operand.valOperand = val;
1352 op->isLiteral = isOperandLiteral (op);
1356 /*-----------------------------------------------------------------*/
1357 /* operandFromLink - operand from typeChain */
1358 /*-----------------------------------------------------------------*/
1360 operandFromLink (sym_link * type)
1364 /* operand from sym_link */
1370 op->operand.typeOperand = copyLinkChain (type);
1374 /*-----------------------------------------------------------------*/
1375 /* operandFromLit - makes an operand from a literal value */
1376 /*-----------------------------------------------------------------*/
1378 operandFromLit (double i)
1380 return operandFromValue (valueFromLit (i));
1383 /*-----------------------------------------------------------------*/
1384 /* operandFromAst - creates an operand from an ast */
1385 /*-----------------------------------------------------------------*/
1387 operandFromAst (ast * tree,int lvl)
1393 /* depending on type do */
1397 return ast2iCode (tree,lvl+1);
1401 return operandFromValue (tree->opval.val);
1405 return operandFromLink (tree->opval.lnk);
1409 /* Just to keep the comiler happy */
1410 return (operand *) 0;
1413 /*-----------------------------------------------------------------*/
1414 /* setOperandType - sets the operand's type to the given type */
1415 /*-----------------------------------------------------------------*/
1417 setOperandType (operand * op, sym_link * type)
1419 /* depending on the type of operand */
1424 op->operand.valOperand->etype =
1425 getSpec (op->operand.valOperand->type =
1426 copyLinkChain (type));
1430 if (op->operand.symOperand->isitmp)
1431 op->operand.symOperand->etype =
1432 getSpec (op->operand.symOperand->type =
1433 copyLinkChain (type));
1435 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1436 "attempt to modify type of source");
1440 op->operand.typeOperand = copyLinkChain (type);
1445 /*-----------------------------------------------------------------*/
1446 /* Get size in byte of ptr need to access an array */
1447 /*-----------------------------------------------------------------*/
1449 getArraySizePtr (operand * op)
1451 sym_link *ltype = operandType(op);
1455 int size = getSize(ltype);
1456 return(IS_GENPTR(ltype)?(size-1):size);
1461 sym_link *letype = getSpec(ltype);
1462 switch (PTR_TYPE (SPEC_OCLS (letype)))
1474 return (GPTRSIZE-1);
1483 /*-----------------------------------------------------------------*/
1484 /* perform "usual unary conversions" */
1485 /*-----------------------------------------------------------------*/
1487 usualUnaryConversions (operand * op)
1489 if (IS_INTEGRAL (operandType (op)))
1491 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1494 return geniCodeCast (INTTYPE, op, TRUE);
1500 /*-----------------------------------------------------------------*/
1501 /* perform "usual binary conversions" */
1502 /*-----------------------------------------------------------------*/
1504 usualBinaryConversions (operand ** op1, operand ** op2)
1507 sym_link *rtype = operandType (*op2);
1508 sym_link *ltype = operandType (*op1);
1510 ctype = computeType (ltype, rtype);
1511 *op1 = geniCodeCast (ctype, *op1, TRUE);
1512 *op2 = geniCodeCast (ctype, *op2, TRUE);
1517 /*-----------------------------------------------------------------*/
1518 /* geniCodeValueAtAddress - generate intermeditate code for value */
1520 /*-----------------------------------------------------------------*/
1522 geniCodeRValue (operand * op, bool force)
1525 sym_link *type = operandType (op);
1526 sym_link *etype = getSpec (type);
1528 /* if this is an array & already */
1529 /* an address then return this */
1530 if (IS_AGGREGATE (type) ||
1531 (IS_PTR (type) && !force && !op->isaddr))
1532 return operandFromOperand (op);
1534 /* if this is not an address then must be */
1535 /* rvalue already so return this one */
1539 /* if this is not a temp symbol then */
1540 if (!IS_ITEMP (op) &&
1542 !IN_FARSPACE (SPEC_OCLS (etype)))
1544 op = operandFromOperand (op);
1549 if (IS_SPEC (type) &&
1550 IS_TRUE_SYMOP (op) &&
1551 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1552 /* TARGET_IS_DS390)) */
1553 (options.model == MODEL_FLAT24) ))
1555 op = operandFromOperand (op);
1560 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1561 if (IS_PTR (type) && op->isaddr && force)
1564 type = copyLinkChain (type);
1566 IC_RESULT (ic) = newiTempOperand (type, 1);
1567 IC_RESULT (ic)->isaddr = 0;
1569 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1571 /* if the right is a symbol */
1572 if (op->type == SYMBOL)
1573 IC_RESULT (ic)->operand.symOperand->args =
1574 op->operand.symOperand->args;
1577 return IC_RESULT (ic);
1580 /*-----------------------------------------------------------------*/
1581 /* geniCodeCast - changes the value from one type to another */
1582 /*-----------------------------------------------------------------*/
1584 geniCodeCast (sym_link * type, operand * op, bool implicit)
1588 sym_link *opetype = getSpec (optype = operandType (op));
1592 /* one of them has size zero then error */
1593 if (IS_VOID (optype))
1595 werror (E_CAST_ZERO);
1599 /* if the operand is already the desired type then do nothing */
1600 if (compareType (type, optype) == 1)
1603 /* if this is a literal then just change the type & return */
1604 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1605 return operandFromValue (valCastLiteral (type,
1606 operandLitValue (op)));
1608 /* if casting to/from pointers, do some checking */
1609 if (IS_PTR(type)) { // to a pointer
1610 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1611 if (IS_INTEGRAL(optype)) {
1612 // maybe this is NULL, than it's ok.
1613 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1614 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1615 // no way to set the storage
1616 if (IS_LITERAL(optype)) {
1617 werror(E_LITERAL_GENERIC);
1620 werror(E_NONPTR2_GENPTR);
1623 } else if (implicit) {
1624 werror(W_INTEGRAL2PTR_NOCAST);
1629 // shouldn't do that with float, array or structure unless to void
1630 if (!IS_VOID(getSpec(type)) &&
1631 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1632 werror(E_INCOMPAT_TYPES);
1636 } else { // from a pointer to a pointer
1637 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1638 // if not a pointer to a function
1639 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1640 if (implicit) { // if not to generic, they have to match
1641 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1642 werror(E_INCOMPAT_PTYPES);
1649 } else { // to a non pointer
1650 if (IS_PTR(optype)) { // from a pointer
1651 if (implicit) { // sneaky
1652 if (IS_INTEGRAL(type)) {
1653 werror(W_PTR2INTEGRAL_NOCAST);
1655 } else { // shouldn't do that with float, array or structure
1656 werror(E_INCOMPAT_TYPES);
1663 /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
1664 implicit?"(implicit)":"", errors); */
1665 fprintf (stderr, "from type '");
1666 printTypeChain (optype, stderr);
1667 fprintf (stderr, "' to type '");
1668 printTypeChain (type, stderr);
1669 fprintf (stderr, "'\n");
1672 /* if they are the same size create an assignment */
1673 if (getSize (type) == getSize (optype) &&
1674 !IS_BITFIELD (type) &&
1676 !IS_FLOAT (optype) &&
1677 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1678 (!IS_SPEC (type) && !IS_SPEC (optype))))
1681 ic = newiCode ('=', NULL, op);
1682 IC_RESULT (ic) = newiTempOperand (type, 0);
1683 SPIL_LOC (IC_RESULT (ic)) =
1684 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1685 IC_RESULT (ic)->isaddr = 0;
1689 ic = newiCode (CAST, operandFromLink (type),
1690 geniCodeRValue (op, FALSE));
1692 IC_RESULT (ic) = newiTempOperand (type, 0);
1695 /* preserve the storage class & output class */
1696 /* of the original variable */
1697 restype = getSpec (operandType (IC_RESULT (ic)));
1698 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1699 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1702 return IC_RESULT (ic);
1705 /*-----------------------------------------------------------------*/
1706 /* geniCodeLabel - will create a Label */
1707 /*-----------------------------------------------------------------*/
1709 geniCodeLabel (symbol * label)
1713 ic = newiCodeLabelGoto (LABEL, label);
1717 /*-----------------------------------------------------------------*/
1718 /* geniCodeGoto - will create a Goto */
1719 /*-----------------------------------------------------------------*/
1721 geniCodeGoto (symbol * label)
1725 ic = newiCodeLabelGoto (GOTO, label);
1729 /*-----------------------------------------------------------------*/
1730 /* geniCodeMultiply - gen intermediate code for multiplication */
1731 /*-----------------------------------------------------------------*/
1733 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1740 /* if they are both literal then we know the result */
1741 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1742 return operandFromValue (valMult (left->operand.valOperand,
1743 right->operand.valOperand));
1745 if (IS_LITERAL(retype)) {
1746 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1749 resType = usualBinaryConversions (&left, &right);
1751 rtype = operandType (right);
1752 retype = getSpec (rtype);
1753 ltype = operandType (left);
1754 letype = getSpec (ltype);
1758 SPEC_NOUN(getSpec(resType))=V_INT;
1761 /* if the right is a literal & power of 2 */
1762 /* then make it a left shift */
1763 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1764 efficient in most cases than 2 bytes result = 2 bytes << literal
1765 if port has 1 byte muldiv */
1766 if (p2 && !IS_FLOAT (letype) &&
1767 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1768 (port->support.muldiv == 1)))
1770 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1772 /* LEFT_OP need same size for left and result, */
1773 left = geniCodeCast (resType, left, TRUE);
1774 ltype = operandType (left);
1776 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1780 ic = newiCode ('*', left, right); /* normal multiplication */
1781 /* if the size left or right > 1 then support routine */
1782 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1786 IC_RESULT (ic) = newiTempOperand (resType, 1);
1789 return IC_RESULT (ic);
1792 /*-----------------------------------------------------------------*/
1793 /* geniCodeDivision - gen intermediate code for division */
1794 /*-----------------------------------------------------------------*/
1796 geniCodeDivision (operand * left, operand * right)
1801 sym_link *rtype = operandType (right);
1802 sym_link *retype = getSpec (rtype);
1803 sym_link *ltype = operandType (left);
1804 sym_link *letype = getSpec (ltype);
1806 resType = usualBinaryConversions (&left, &right);
1808 /* if the right is a literal & power of 2 */
1809 /* then make it a right shift */
1810 if (IS_LITERAL (retype) &&
1811 !IS_FLOAT (letype) &&
1812 (p2 = powof2 ((unsigned long)
1813 floatFromVal (right->operand.valOperand)))) {
1814 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1818 ic = newiCode ('/', left, right); /* normal division */
1819 /* if the size left or right > 1 then support routine */
1820 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1823 IC_RESULT (ic) = newiTempOperand (resType, 0);
1826 return IC_RESULT (ic);
1828 /*-----------------------------------------------------------------*/
1829 /* geniCodeModulus - gen intermediate code for modulus */
1830 /*-----------------------------------------------------------------*/
1832 geniCodeModulus (operand * left, operand * right)
1838 /* if they are both literal then we know the result */
1839 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1840 return operandFromValue (valMod (left->operand.valOperand,
1841 right->operand.valOperand));
1843 resType = usualBinaryConversions (&left, &right);
1845 /* now they are the same size */
1846 ic = newiCode ('%', left, right);
1848 /* if the size left or right > 1 then support routine */
1849 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1851 IC_RESULT (ic) = newiTempOperand (resType, 0);
1854 return IC_RESULT (ic);
1857 /*-----------------------------------------------------------------*/
1858 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1859 /*-----------------------------------------------------------------*/
1861 geniCodePtrPtrSubtract (operand * left, operand * right)
1867 /* if they are both literals then */
1868 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1870 result = operandFromValue (valMinus (left->operand.valOperand,
1871 right->operand.valOperand));
1875 ic = newiCode ('-', left, right);
1877 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1881 return geniCodeDivision (result,
1882 operandFromLit (getSize (ltype->next)));
1885 /*-----------------------------------------------------------------*/
1886 /* geniCodeSubtract - generates code for subtraction */
1887 /*-----------------------------------------------------------------*/
1889 geniCodeSubtract (operand * left, operand * right)
1896 /* if they both pointers then */
1897 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1898 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1899 return geniCodePtrPtrSubtract (left, right);
1901 /* if they are both literal then we know the result */
1902 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1903 && left->isLiteral && right->isLiteral)
1904 return operandFromValue (valMinus (left->operand.valOperand,
1905 right->operand.valOperand));
1907 /* if left is an array or pointer */
1908 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1910 isarray = left->isaddr;
1911 right = geniCodeMultiply (right,
1912 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1913 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1916 { /* make them the same size */
1917 resType = usualBinaryConversions (&left, &right);
1920 ic = newiCode ('-', left, right);
1922 IC_RESULT (ic) = newiTempOperand (resType, 1);
1923 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1925 /* if left or right is a float */
1926 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1930 return IC_RESULT (ic);
1933 /*-----------------------------------------------------------------*/
1934 /* geniCodeAdd - generates iCode for addition */
1935 /*-----------------------------------------------------------------*/
1937 geniCodeAdd (operand * left, operand * right,int lvl)
1945 /* if left is an array then array access */
1946 if (IS_ARRAY (ltype))
1947 return geniCodeArray (left, right,lvl);
1949 /* if the right side is LITERAL zero */
1950 /* return the left side */
1951 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1954 /* if left is literal zero return right */
1955 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1958 /* if left is an array or pointer then size */
1961 isarray = left->isaddr;
1962 // there is no need to multiply with 1
1963 if (getSize(ltype->next)!=1) {
1964 size = operandFromLit (getSize (ltype->next));
1965 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1967 resType = copyLinkChain (ltype);
1970 { /* make them the same size */
1971 resType = usualBinaryConversions (&left, &right);
1974 /* if they are both literals then we know */
1975 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1976 && left->isLiteral && right->isLiteral)
1977 return operandFromValue (valPlus (valFromType (letype),
1978 valFromType (retype)));
1980 ic = newiCode ('+', left, right);
1982 IC_RESULT (ic) = newiTempOperand (resType, 1);
1983 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1985 /* if left or right is a float then support
1987 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1992 return IC_RESULT (ic);
1996 /*-----------------------------------------------------------------*/
1997 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1998 /*-----------------------------------------------------------------*/
2000 aggrToPtr (sym_link * type, bool force)
2006 if (IS_PTR (type) && !force)
2009 etype = getSpec (type);
2013 /* if the output class is generic */
2014 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2015 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2017 /* if the variable was declared a constant */
2018 /* then the pointer points to a constant */
2019 if (IS_CONSTANT (etype))
2020 DCL_PTR_CONST (ptype) = 1;
2022 /* the variable was volatile then pointer to volatile */
2023 if (IS_VOLATILE (etype))
2024 DCL_PTR_VOLATILE (ptype) = 1;
2028 /*-----------------------------------------------------------------*/
2029 /* geniCodeArray2Ptr - array to pointer */
2030 /*-----------------------------------------------------------------*/
2032 geniCodeArray2Ptr (operand * op)
2034 sym_link *optype = operandType (op);
2035 sym_link *opetype = getSpec (optype);
2037 /* set the pointer depending on the storage class */
2038 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2039 DCL_PTR_CONST (optype) = port->mem.code_ro;
2042 /* if the variable was declared a constant */
2043 /* then the pointer points to a constant */
2044 if (IS_CONSTANT (opetype))
2045 DCL_PTR_CONST (optype) = 1;
2047 /* the variable was volatile then pointer to volatile */
2048 if (IS_VOLATILE (opetype))
2049 DCL_PTR_VOLATILE (optype) = 1;
2055 /*-----------------------------------------------------------------*/
2056 /* geniCodeArray - array access */
2057 /*-----------------------------------------------------------------*/
2059 geniCodeArray (operand * left, operand * right,int lvl)
2062 sym_link *ltype = operandType (left);
2066 if (IS_PTR (ltype->next) && left->isaddr)
2068 left = geniCodeRValue (left, FALSE);
2070 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2073 right = geniCodeMultiply (right,
2074 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2076 /* we can check for limits here */
2077 if (isOperandLiteral (right) &&
2080 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2082 werror (E_ARRAY_BOUND);
2083 right = operandFromLit (0);
2086 ic = newiCode ('+', left, right);
2088 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2089 !IS_AGGREGATE (ltype->next) &&
2090 !IS_PTR (ltype->next))
2091 ? ltype : ltype->next), 0);
2093 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2095 return IC_RESULT (ic);
2098 /*-----------------------------------------------------------------*/
2099 /* geniCodeStruct - generates intermediate code for structres */
2100 /*-----------------------------------------------------------------*/
2102 geniCodeStruct (operand * left, operand * right, bool islval)
2105 sym_link *type = operandType (left);
2106 sym_link *etype = getSpec (type);
2108 symbol *element = getStructElement (SPEC_STRUCT (etype),
2109 right->operand.symOperand);
2111 /* add the offset */
2112 ic = newiCode ('+', left, operandFromLit (element->offset));
2114 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2116 /* preserve the storage & output class of the struct */
2117 /* as well as the volatile attribute */
2118 retype = getSpec (operandType (IC_RESULT (ic)));
2119 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2120 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2121 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2123 if (IS_PTR (element->type))
2124 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2126 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2130 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2133 /*-----------------------------------------------------------------*/
2134 /* geniCodePostInc - generate int code for Post increment */
2135 /*-----------------------------------------------------------------*/
2137 geniCodePostInc (operand * op)
2141 sym_link *optype = operandType (op);
2143 operand *rv = (IS_ITEMP (op) ?
2144 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2146 sym_link *rvtype = operandType (rv);
2149 /* if this is not an address we have trouble */
2152 werror (E_LVALUE_REQUIRED, "++");
2156 rOp = newiTempOperand (rvtype, 0);
2157 OP_SYMBOL(rOp)->noSpilLoc = 1;
2160 OP_SYMBOL(rv)->noSpilLoc = 1;
2162 geniCodeAssign (rOp, rv, 0);
2164 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2165 if (IS_FLOAT (rvtype))
2166 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2168 ic = newiCode ('+', rv, operandFromLit (size));
2170 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2173 geniCodeAssign (op, result, 0);
2179 /*-----------------------------------------------------------------*/
2180 /* geniCodePreInc - generate code for preIncrement */
2181 /*-----------------------------------------------------------------*/
2183 geniCodePreInc (operand * op)
2186 sym_link *optype = operandType (op);
2187 operand *rop = (IS_ITEMP (op) ?
2188 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2190 sym_link *roptype = operandType (rop);
2196 werror (E_LVALUE_REQUIRED, "++");
2201 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2202 if (IS_FLOAT (roptype))
2203 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2205 ic = newiCode ('+', rop, operandFromLit (size));
2206 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2210 return geniCodeAssign (op, result, 0);
2213 /*-----------------------------------------------------------------*/
2214 /* geniCodePostDec - generates code for Post decrement */
2215 /*-----------------------------------------------------------------*/
2217 geniCodePostDec (operand * op)
2221 sym_link *optype = operandType (op);
2223 operand *rv = (IS_ITEMP (op) ?
2224 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2226 sym_link *rvtype = operandType (rv);
2229 /* if this is not an address we have trouble */
2232 werror (E_LVALUE_REQUIRED, "--");
2236 rOp = newiTempOperand (rvtype, 0);
2237 OP_SYMBOL(rOp)->noSpilLoc = 1;
2240 OP_SYMBOL(rv)->noSpilLoc = 1;
2242 geniCodeAssign (rOp, rv, 0);
2244 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2245 if (IS_FLOAT (rvtype))
2246 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2248 ic = newiCode ('-', rv, operandFromLit (size));
2250 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2253 geniCodeAssign (op, result, 0);
2259 /*-----------------------------------------------------------------*/
2260 /* geniCodePreDec - generate code for pre decrement */
2261 /*-----------------------------------------------------------------*/
2263 geniCodePreDec (operand * op)
2266 sym_link *optype = operandType (op);
2267 operand *rop = (IS_ITEMP (op) ?
2268 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2270 sym_link *roptype = operandType (rop);
2276 werror (E_LVALUE_REQUIRED, "--");
2281 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2282 if (IS_FLOAT (roptype))
2283 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2285 ic = newiCode ('-', rop, operandFromLit (size));
2286 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2290 return geniCodeAssign (op, result, 0);
2294 /*-----------------------------------------------------------------*/
2295 /* geniCodeBitwise - gen int code for bitWise operators */
2296 /*-----------------------------------------------------------------*/
2298 geniCodeBitwise (operand * left, operand * right,
2299 int oper, sym_link * resType)
2303 left = geniCodeCast (resType, left, TRUE);
2304 right = geniCodeCast (resType, right, TRUE);
2306 ic = newiCode (oper, left, right);
2307 IC_RESULT (ic) = newiTempOperand (resType, 0);
2310 return IC_RESULT (ic);
2313 /*-----------------------------------------------------------------*/
2314 /* geniCodeAddressOf - gens icode for '&' address of operator */
2315 /*-----------------------------------------------------------------*/
2317 geniCodeAddressOf (operand * op)
2321 sym_link *optype = operandType (op);
2322 sym_link *opetype = getSpec (optype);
2324 /* lvalue check already done in decorateType */
2325 /* this must be a lvalue */
2326 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2327 /* werror (E_LVALUE_REQUIRED,"&"); */
2332 p->class = DECLARATOR;
2334 /* set the pointer depending on the storage class */
2335 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2336 DCL_PTR_CONST (p) = port->mem.code_ro;
2338 /* make sure we preserve the const & volatile */
2339 if (IS_CONSTANT (opetype))
2340 DCL_PTR_CONST (p) = 1;
2342 if (IS_VOLATILE (opetype))
2343 DCL_PTR_VOLATILE (p) = 1;
2345 p->next = copyLinkChain (optype);
2347 /* if already a temp */
2350 setOperandType (op, p);
2355 /* other wise make this of the type coming in */
2356 ic = newiCode (ADDRESS_OF, op, NULL);
2357 IC_RESULT (ic) = newiTempOperand (p, 1);
2358 IC_RESULT (ic)->isaddr = 0;
2360 return IC_RESULT (ic);
2362 /*-----------------------------------------------------------------*/
2363 /* setOClass - sets the output class depending on the pointer type */
2364 /*-----------------------------------------------------------------*/
2366 setOClass (sym_link * ptr, sym_link * spec)
2368 switch (DCL_TYPE (ptr))
2371 SPEC_OCLS (spec) = data;
2375 SPEC_OCLS (spec) = generic;
2379 SPEC_OCLS (spec) = xdata;
2383 SPEC_OCLS (spec) = code;
2387 SPEC_OCLS (spec) = idata;
2391 SPEC_OCLS (spec) = xstack;
2395 SPEC_OCLS (spec) = eeprom;
2404 /*-----------------------------------------------------------------*/
2405 /* geniCodeDerefPtr - dereference pointer with '*' */
2406 /*-----------------------------------------------------------------*/
2408 geniCodeDerefPtr (operand * op,int lvl)
2410 sym_link *rtype, *retype;
2411 sym_link *optype = operandType (op);
2413 /* if this is a pointer then generate the rvalue */
2414 if (IS_PTR (optype))
2416 if (IS_TRUE_SYMOP (op))
2419 op = geniCodeRValue (op, TRUE);
2422 op = geniCodeRValue (op, TRUE);
2425 /* now get rid of the pointer part */
2426 if (isLvaluereq(lvl) && IS_ITEMP (op))
2428 retype = getSpec (rtype = copyLinkChain (optype));
2432 retype = getSpec (rtype = copyLinkChain (optype->next));
2435 /* if this is a pointer then outputclass needs 2b updated */
2436 if (IS_PTR (optype))
2437 setOClass (optype, retype);
2439 op->isGptr = IS_GENPTR (optype);
2441 /* if the pointer was declared as a constant */
2442 /* then we cannot allow assignment to the derefed */
2443 if (IS_PTR_CONST (optype))
2444 SPEC_CONST (retype) = 1;
2446 op->isaddr = (IS_PTR (rtype) ||
2447 IS_STRUCT (rtype) ||
2452 if (!isLvaluereq(lvl))
2453 op = geniCodeRValue (op, TRUE);
2455 setOperandType (op, rtype);
2460 /*-----------------------------------------------------------------*/
2461 /* geniCodeUnaryMinus - does a unary minus of the operand */
2462 /*-----------------------------------------------------------------*/
2464 geniCodeUnaryMinus (operand * op)
2467 sym_link *optype = operandType (op);
2469 if (IS_LITERAL (optype))
2470 return operandFromLit (-floatFromVal (op->operand.valOperand));
2472 ic = newiCode (UNARYMINUS, op, NULL);
2473 IC_RESULT (ic) = newiTempOperand (optype, 0);
2475 return IC_RESULT (ic);
2478 /*-----------------------------------------------------------------*/
2479 /* geniCodeLeftShift - gen i code for left shift */
2480 /*-----------------------------------------------------------------*/
2482 geniCodeLeftShift (operand * left, operand * right)
2486 ic = newiCode (LEFT_OP, left, right);
2487 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2489 return IC_RESULT (ic);
2492 /*-----------------------------------------------------------------*/
2493 /* geniCodeRightShift - gen i code for right shift */
2494 /*-----------------------------------------------------------------*/
2496 geniCodeRightShift (operand * left, operand * right)
2500 ic = newiCode (RIGHT_OP, left, right);
2501 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2503 return IC_RESULT (ic);
2506 /*-----------------------------------------------------------------*/
2507 /* geniCodeLogic- logic code */
2508 /*-----------------------------------------------------------------*/
2510 geniCodeLogic (operand * left, operand * right, int op)
2514 sym_link *rtype = operandType (right);
2515 sym_link *ltype = operandType (left);
2517 /* left is integral type and right is literal then
2518 check if the literal value is within bounds */
2519 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2521 checkConstantRange(ltype,
2522 OP_VALUE(right), "compare operation", 1);
2525 ctype = usualBinaryConversions (&left, &right);
2527 ic = newiCode (op, left, right);
2528 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2530 /* if comparing float
2531 and not a '==' || '!=' || '&&' || '||' (these
2533 if (IS_FLOAT(ctype) &&
2541 return IC_RESULT (ic);
2544 /*-----------------------------------------------------------------*/
2545 /* geniCodeUnary - for a a generic unary operation */
2546 /*-----------------------------------------------------------------*/
2548 geniCodeUnary (operand * op, int oper)
2550 iCode *ic = newiCode (oper, op, NULL);
2552 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2554 return IC_RESULT (ic);
2557 /*-----------------------------------------------------------------*/
2558 /* geniCodeConditional - geniCode for '?' ':' operation */
2559 /*-----------------------------------------------------------------*/
2561 geniCodeConditional (ast * tree,int lvl)
2564 symbol *falseLabel = newiTempLabel (NULL);
2565 symbol *exitLabel = newiTempLabel (NULL);
2566 operand *cond = ast2iCode (tree->left,lvl+1);
2567 operand *true, *false, *result;
2569 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2573 true = ast2iCode (tree->right->left,lvl+1);
2575 /* move the value to a new Operand */
2576 result = newiTempOperand (operandType (true), 0);
2577 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2579 /* generate an unconditional goto */
2580 geniCodeGoto (exitLabel);
2582 /* now for the right side */
2583 geniCodeLabel (falseLabel);
2585 false = ast2iCode (tree->right->right,lvl+1);
2586 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2588 /* create the exit label */
2589 geniCodeLabel (exitLabel);
2594 /*-----------------------------------------------------------------*/
2595 /* geniCodeAssign - generate code for assignment */
2596 /*-----------------------------------------------------------------*/
2598 geniCodeAssign (operand * left, operand * right, int nosupdate)
2601 sym_link *ltype = operandType (left);
2602 sym_link *rtype = operandType (right);
2604 if (!left->isaddr && !IS_ITEMP (left))
2606 werror (E_LVALUE_REQUIRED, "assignment");
2610 /* left is integral type and right is literal then
2611 check if the literal value is within bounds */
2612 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2614 checkConstantRange(ltype,
2615 OP_VALUE(right), "= operation", 0);
2618 /* if the left & right type don't exactly match */
2619 /* if pointer set then make sure the check is
2620 done with the type & not the pointer */
2621 /* then cast rights type to left */
2623 /* first check the type for pointer assignement */
2624 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2625 compareType (ltype, rtype) < 0)
2627 if (compareType (ltype->next, rtype) < 0)
2628 right = geniCodeCast (ltype->next, right, TRUE);
2630 else if (compareType (ltype, rtype) < 0)
2631 right = geniCodeCast (ltype, right, TRUE);
2633 /* if left is a true symbol & ! volatile
2634 create an assignment to temporary for
2635 the right & then assign this temporary
2636 to the symbol this is SSA . isn't it simple
2637 and folks have published mountains of paper on it */
2638 if (IS_TRUE_SYMOP (left) &&
2639 !isOperandVolatile (left, FALSE) &&
2640 isOperandGlobal (left))
2644 if (IS_TRUE_SYMOP (right))
2645 sym = OP_SYMBOL (right);
2646 ic = newiCode ('=', NULL, right);
2647 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2648 SPIL_LOC (right) = sym;
2652 ic = newiCode ('=', NULL, right);
2653 IC_RESULT (ic) = left;
2656 /* if left isgptr flag is set then support
2657 routine will be required */
2661 ic->nosupdate = nosupdate;
2665 /*-----------------------------------------------------------------*/
2666 /* geniCodeSEParms - generate code for side effecting fcalls */
2667 /*-----------------------------------------------------------------*/
2669 geniCodeSEParms (ast * parms,int lvl)
2674 if (parms->type == EX_OP && parms->opval.op == PARAM)
2676 geniCodeSEParms (parms->left,lvl);
2677 geniCodeSEParms (parms->right,lvl);
2681 /* hack don't like this but too lazy to think of
2683 if (IS_ADDRESS_OF_OP (parms))
2684 parms->left->lvalue = 1;
2686 if (IS_CAST_OP (parms) &&
2687 IS_PTR (parms->ftype) &&
2688 IS_ADDRESS_OF_OP (parms->right))
2689 parms->right->left->lvalue = 1;
2691 parms->opval.oprnd =
2692 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2694 parms->type = EX_OPERAND;
2697 /*-----------------------------------------------------------------*/
2698 /* geniCodeParms - generates parameters */
2699 /*-----------------------------------------------------------------*/
2701 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2709 /* if this is a param node then do the left & right */
2710 if (parms->type == EX_OP && parms->opval.op == PARAM)
2712 geniCodeParms (parms->left, stack, fetype, func,lvl);
2713 geniCodeParms (parms->right, stack, fetype, func,lvl);
2717 /* get the parameter value */
2718 if (parms->type == EX_OPERAND)
2719 pval = parms->opval.oprnd;
2722 /* maybe this else should go away ?? */
2723 /* hack don't like this but too lazy to think of
2725 if (IS_ADDRESS_OF_OP (parms))
2726 parms->left->lvalue = 1;
2728 if (IS_CAST_OP (parms) &&
2729 IS_PTR (parms->ftype) &&
2730 IS_ADDRESS_OF_OP (parms->right))
2731 parms->right->left->lvalue = 1;
2733 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2736 /* if register parm then make it a send */
2737 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2738 IS_REGPARM (parms->etype)) && !func->hasVargs)
2740 ic = newiCode (SEND, pval, NULL);
2745 /* now decide whether to push or assign */
2746 if (!(options.stackAuto || IS_RENT (fetype)))
2750 operand *top = operandFromSymbol (parms->argSym);
2751 geniCodeAssign (top, pval, 1);
2755 sym_link *p = operandType (pval);
2757 ic = newiCode (IPUSH, pval, NULL);
2759 /* update the stack adjustment */
2760 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2767 /*-----------------------------------------------------------------*/
2768 /* geniCodeCall - generates temp code for calling */
2769 /*-----------------------------------------------------------------*/
2771 geniCodeCall (operand * left, ast * parms,int lvl)
2775 sym_link *type, *etype;
2778 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2779 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2780 werror (E_FUNCTION_EXPECTED);
2784 /* take care of parameters with side-effecting
2785 function calls in them, this is required to take care
2786 of overlaying function parameters */
2787 geniCodeSEParms (parms,lvl);
2789 /* first the parameters */
2790 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2792 /* now call : if symbol then pcall */
2793 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2794 ic = newiCode (PCALL, left, NULL);
2796 ic = newiCode (CALL, left, NULL);
2798 IC_ARGS (ic) = left->operand.symOperand->args;
2799 type = copyLinkChain (operandType (left)->next);
2800 etype = getSpec (type);
2801 SPEC_EXTR (etype) = 0;
2802 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2806 /* stack adjustment after call */
2807 ic->parmBytes = stack;
2812 /*-----------------------------------------------------------------*/
2813 /* geniCodeReceive - generate intermediate code for "receive" */
2814 /*-----------------------------------------------------------------*/
2816 geniCodeReceive (value * args)
2818 /* for all arguments that are passed in registers */
2822 if (IS_REGPARM (args->etype))
2824 operand *opr = operandFromValue (args);
2826 symbol *sym = OP_SYMBOL (opr);
2829 /* we will use it after all optimizations
2830 and before liveRange calculation */
2831 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2834 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2835 options.stackAuto == 0 &&
2836 /* !TARGET_IS_DS390) */
2837 (!(options.model == MODEL_FLAT24)) )
2842 opl = newiTempOperand (args->type, 0);
2844 sym->reqv->key = sym->key;
2845 OP_SYMBOL (sym->reqv)->key = sym->key;
2846 OP_SYMBOL (sym->reqv)->isreqv = 1;
2847 OP_SYMBOL (sym->reqv)->islocal = 0;
2848 SPIL_LOC (sym->reqv) = sym;
2852 ic = newiCode (RECEIVE, NULL, NULL);
2853 currFunc->recvSize = getSize (sym->etype);
2854 IC_RESULT (ic) = opr;
2862 /*-----------------------------------------------------------------*/
2863 /* geniCodeFunctionBody - create the function body */
2864 /*-----------------------------------------------------------------*/
2866 geniCodeFunctionBody (ast * tree,int lvl)
2873 /* reset the auto generation */
2879 func = ast2iCode (tree->left,lvl+1);
2880 fetype = getSpec (operandType (func));
2882 savelineno = lineno;
2883 lineno = OP_SYMBOL (func)->lineDef;
2884 /* create an entry label */
2885 geniCodeLabel (entryLabel);
2886 lineno = savelineno;
2888 /* create a proc icode */
2889 ic = newiCode (FUNCTION, func, NULL);
2890 /* if the function has parmas then */
2891 /* save the parameters information */
2892 ic->argLabel.args = tree->values.args;
2893 ic->lineno = OP_SYMBOL (func)->lineDef;
2897 /* for all parameters that are passed
2898 on registers add a "receive" */
2899 geniCodeReceive (tree->values.args);
2901 /* generate code for the body */
2902 ast2iCode (tree->right,lvl+1);
2904 /* create a label for return */
2905 geniCodeLabel (returnLabel);
2907 /* now generate the end proc */
2908 ic = newiCode (ENDFUNCTION, func, NULL);
2913 /*-----------------------------------------------------------------*/
2914 /* geniCodeReturn - gen icode for 'return' statement */
2915 /*-----------------------------------------------------------------*/
2917 geniCodeReturn (operand * op)
2921 /* if the operand is present force an rvalue */
2923 op = geniCodeRValue (op, FALSE);
2925 ic = newiCode (RETURN, op, NULL);
2929 /*-----------------------------------------------------------------*/
2930 /* geniCodeIfx - generates code for extended if statement */
2931 /*-----------------------------------------------------------------*/
2933 geniCodeIfx (ast * tree,int lvl)
2936 operand *condition = ast2iCode (tree->left,lvl+1);
2939 /* if condition is null then exit */
2943 condition = geniCodeRValue (condition, FALSE);
2945 cetype = getSpec (operandType (condition));
2946 /* if the condition is a literal */
2947 if (IS_LITERAL (cetype))
2949 if (floatFromVal (condition->operand.valOperand))
2951 if (tree->trueLabel)
2952 geniCodeGoto (tree->trueLabel);
2958 if (tree->falseLabel)
2959 geniCodeGoto (tree->falseLabel);
2966 if (tree->trueLabel)
2968 ic = newiCodeCondition (condition,
2973 if (tree->falseLabel)
2974 geniCodeGoto (tree->falseLabel);
2978 ic = newiCodeCondition (condition,
2985 ast2iCode (tree->right,lvl+1);
2988 /*-----------------------------------------------------------------*/
2989 /* geniCodeJumpTable - tries to create a jump table for switch */
2990 /*-----------------------------------------------------------------*/
2992 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2994 int min = 0, max = 0, t, cnt = 0;
3001 if (!tree || !caseVals)
3004 /* the criteria for creating a jump table is */
3005 /* all integer numbers between the maximum & minimum must */
3006 /* be present , the maximum value should not exceed 255 */
3007 min = max = (int) floatFromVal (vch = caseVals);
3008 sprintf (buffer, "_case_%d_%d",
3009 tree->values.switchVals.swNum,
3011 addSet (&labels, newiTempLabel (buffer));
3013 /* if there is only one case value then no need */
3014 if (!(vch = vch->next))
3019 if (((t = (int) floatFromVal (vch)) - max) != 1)
3021 sprintf (buffer, "_case_%d_%d",
3022 tree->values.switchVals.swNum,
3024 addSet (&labels, newiTempLabel (buffer));
3030 /* if the number of case statements <= 2 then */
3031 /* it is not economical to create the jump table */
3032 /* since two compares are needed for boundary conditions */
3033 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3036 if (tree->values.switchVals.swDefault)
3037 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3039 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3041 falseLabel = newiTempLabel (buffer);
3043 /* so we can create a jumptable */
3044 /* first we rule out the boundary conditions */
3045 /* if only optimization says so */
3046 if (!optimize.noJTabBoundary)
3048 sym_link *cetype = getSpec (operandType (cond));
3049 /* no need to check the lower bound if
3050 the condition is unsigned & minimum value is zero */
3051 if (!(min == 0 && SPEC_USIGN (cetype)))
3053 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3054 ic = newiCodeCondition (boundary, falseLabel, NULL);
3058 /* now for upper bounds */
3059 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3060 ic = newiCodeCondition (boundary, falseLabel, NULL);
3064 /* if the min is not zero then we no make it zero */
3067 cond = geniCodeSubtract (cond, operandFromLit (min));
3068 setOperandType (cond, UCHARTYPE);
3071 /* now create the jumptable */
3072 ic = newiCode (JUMPTABLE, NULL, NULL);
3073 IC_JTCOND (ic) = cond;
3074 IC_JTLABELS (ic) = labels;
3079 /*-----------------------------------------------------------------*/
3080 /* geniCodeSwitch - changes a switch to a if statement */
3081 /*-----------------------------------------------------------------*/
3083 geniCodeSwitch (ast * tree,int lvl)
3086 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3087 value *caseVals = tree->values.switchVals.swVals;
3088 symbol *trueLabel, *falseLabel;
3090 /* if we can make this a jump table */
3091 if (geniCodeJumpTable (cond, caseVals, tree))
3092 goto jumpTable; /* no need for the comparison */
3094 /* for the cases defined do */
3098 operand *compare = geniCodeLogic (cond,
3099 operandFromValue (caseVals),
3102 sprintf (buffer, "_case_%d_%d",
3103 tree->values.switchVals.swNum,
3104 (int) floatFromVal (caseVals));
3105 trueLabel = newiTempLabel (buffer);
3107 ic = newiCodeCondition (compare, trueLabel, NULL);
3109 caseVals = caseVals->next;
3114 /* if default is present then goto break else break */
3115 if (tree->values.switchVals.swDefault)
3116 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3118 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3120 falseLabel = newiTempLabel (buffer);
3121 geniCodeGoto (falseLabel);
3124 ast2iCode (tree->right,lvl+1);
3127 /*-----------------------------------------------------------------*/
3128 /* geniCodeInline - intermediate code for inline assembler */
3129 /*-----------------------------------------------------------------*/
3131 geniCodeInline (ast * tree)
3135 ic = newiCode (INLINEASM, NULL, NULL);
3136 IC_INLINE (ic) = tree->values.inlineasm;
3140 /*-----------------------------------------------------------------*/
3141 /* geniCodeArrayInit - intermediate code for array initializer */
3142 /*-----------------------------------------------------------------*/
3144 geniCodeArrayInit (ast * tree, operand *array)
3148 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3149 ic = newiCode (ARRAYINIT, array, NULL);
3150 IC_ARRAYILIST (ic) = tree->values.constlist;
3152 operand *left=newOperand(), *right=newOperand();
3153 left->type=right->type=SYMBOL;
3154 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3155 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3156 ic = newiCode (ARRAYINIT, left, right);
3161 /*-----------------------------------------------------------------*/
3162 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3163 /* particular case. Ie : assigning or dereferencing array or ptr */
3164 /*-----------------------------------------------------------------*/
3165 set * lvaluereqSet = NULL;
3166 typedef struct lvalItem
3173 /*-----------------------------------------------------------------*/
3174 /* addLvaluereq - add a flag for lvalreq for current ast level */
3175 /*-----------------------------------------------------------------*/
3176 void addLvaluereq(int lvl)
3178 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3181 addSetHead(&lvaluereqSet,lpItem);
3184 /*-----------------------------------------------------------------*/
3185 /* delLvaluereq - del a flag for lvalreq for current ast level */
3186 /*-----------------------------------------------------------------*/
3190 lpItem = getSet(&lvaluereqSet);
3191 if(lpItem) Safe_free(lpItem);
3193 /*-----------------------------------------------------------------*/
3194 /* clearLvaluereq - clear lvalreq flag */
3195 /*-----------------------------------------------------------------*/
3196 void clearLvaluereq()
3199 lpItem = peekSet(lvaluereqSet);
3200 if(lpItem) lpItem->req = 0;
3202 /*-----------------------------------------------------------------*/
3203 /* getLvaluereq - get the last lvalreq level */
3204 /*-----------------------------------------------------------------*/
3205 int getLvaluereqLvl()
3208 lpItem = peekSet(lvaluereqSet);
3209 if(lpItem) return lpItem->lvl;
3212 /*-----------------------------------------------------------------*/
3213 /* isLvaluereq - is lvalreq valid for this level ? */
3214 /*-----------------------------------------------------------------*/
3215 int isLvaluereq(int lvl)
3218 lpItem = peekSet(lvaluereqSet);
3219 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3223 /*-----------------------------------------------------------------*/
3224 /* ast2iCode - creates an icodeList from an ast */
3225 /*-----------------------------------------------------------------*/
3227 ast2iCode (ast * tree,int lvl)
3229 operand *left = NULL;
3230 operand *right = NULL;
3233 /* set the global variables for filename & line number */
3235 filename = tree->filename;
3237 lineno = tree->lineno;
3239 block = tree->block;
3241 scopeLevel = tree->level;
3243 if (tree->type == EX_VALUE)
3244 return operandFromValue (tree->opval.val);
3246 if (tree->type == EX_LINK)
3247 return operandFromLink (tree->opval.lnk);
3249 /* if we find a nullop */
3250 if (tree->type == EX_OP &&
3251 (tree->opval.op == NULLOP ||
3252 tree->opval.op == BLOCK))
3254 ast2iCode (tree->left,lvl+1);
3255 ast2iCode (tree->right,lvl+1);
3259 /* special cases for not evaluating */
3260 if (tree->opval.op != ':' &&
3261 tree->opval.op != '?' &&
3262 tree->opval.op != CALL &&
3263 tree->opval.op != IFX &&
3264 tree->opval.op != LABEL &&
3265 tree->opval.op != GOTO &&
3266 tree->opval.op != SWITCH &&
3267 tree->opval.op != FUNCTION &&
3268 tree->opval.op != INLINEASM)
3271 if (IS_ASSIGN_OP (tree->opval.op) ||
3272 IS_DEREF_OP (tree) ||
3273 (tree->opval.op == '&' && !tree->right) ||
3274 tree->opval.op == PTR_OP)
3277 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3278 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3281 left = operandFromAst (tree->left,lvl);
3283 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3284 left = geniCodeRValue (left, TRUE);
3288 left = operandFromAst (tree->left,lvl);
3290 if (tree->opval.op == INC_OP ||
3291 tree->opval.op == DEC_OP)
3294 right = operandFromAst (tree->right,lvl);
3299 right = operandFromAst (tree->right,lvl);
3303 /* now depending on the type of operand */
3304 /* this will be a biggy */
3305 switch (tree->opval.op)
3308 case '[': /* array operation */
3310 //sym_link *ltype = operandType (left);
3311 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3312 left = geniCodeRValue (left, FALSE);
3313 right = geniCodeRValue (right, TRUE);
3316 return geniCodeArray (left, right,lvl);
3318 case '.': /* structure dereference */
3319 if (IS_PTR (operandType (left)))
3320 left = geniCodeRValue (left, TRUE);
3322 left = geniCodeRValue (left, FALSE);
3324 return geniCodeStruct (left, right, tree->lvalue);
3326 case PTR_OP: /* structure pointer dereference */
3329 pType = operandType (left);
3330 left = geniCodeRValue (left, TRUE);
3332 setOClass (pType, getSpec (operandType (left)));
3335 return geniCodeStruct (left, right, tree->lvalue);
3337 case INC_OP: /* increment operator */
3339 return geniCodePostInc (left);
3341 return geniCodePreInc (right);
3343 case DEC_OP: /* decrement operator */
3345 return geniCodePostDec (left);
3347 return geniCodePreDec (right);
3349 case '&': /* bitwise and or address of operator */
3351 { /* this is a bitwise operator */
3352 left = geniCodeRValue (left, FALSE);
3353 right = geniCodeRValue (right, FALSE);
3354 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3357 return geniCodeAddressOf (left);
3359 case '|': /* bitwise or & xor */
3361 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3362 geniCodeRValue (right, FALSE),
3367 return geniCodeDivision (geniCodeRValue (left, FALSE),
3368 geniCodeRValue (right, FALSE));
3371 return geniCodeModulus (geniCodeRValue (left, FALSE),
3372 geniCodeRValue (right, FALSE));
3375 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3376 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3378 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3382 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3383 geniCodeRValue (right, FALSE));
3385 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3389 return geniCodeAdd (geniCodeRValue (left, FALSE),
3390 geniCodeRValue (right, FALSE),lvl);
3392 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3395 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3396 geniCodeRValue (right, FALSE));
3399 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3400 geniCodeRValue (right, FALSE));
3402 return geniCodeCast (operandType (left),
3403 geniCodeRValue (right, FALSE), FALSE);
3409 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3413 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3414 setOperandType (op, UCHARTYPE);
3425 return geniCodeLogic (geniCodeRValue (left, FALSE),
3426 geniCodeRValue (right, FALSE),
3429 return geniCodeConditional (tree,lvl);
3432 return operandFromLit (getSize (tree->right->ftype));
3436 sym_link *rtype = operandType (right);
3437 sym_link *ltype = operandType (left);
3438 if (IS_PTR (rtype) && IS_ITEMP (right)
3439 && right->isaddr && compareType (rtype->next, ltype) == 1)
3440 right = geniCodeRValue (right, TRUE);
3442 right = geniCodeRValue (right, FALSE);
3444 geniCodeAssign (left, right, 0);
3449 geniCodeAssign (left,
3450 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3452 geniCodeRValue (right, FALSE),FALSE), 0);
3456 geniCodeAssign (left,
3457 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3459 geniCodeRValue (right, FALSE)), 0);
3462 geniCodeAssign (left,
3463 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3465 geniCodeRValue (right, FALSE)), 0);
3468 sym_link *rtype = operandType (right);
3469 sym_link *ltype = operandType (left);
3470 if (IS_PTR (rtype) && IS_ITEMP (right)
3471 && right->isaddr && compareType (rtype->next, ltype) == 1)
3472 right = geniCodeRValue (right, TRUE);
3474 right = geniCodeRValue (right, FALSE);
3477 return geniCodeAssign (left,
3478 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3484 sym_link *rtype = operandType (right);
3485 sym_link *ltype = operandType (left);
3486 if (IS_PTR (rtype) && IS_ITEMP (right)
3487 && right->isaddr && compareType (rtype->next, ltype) == 1)
3489 right = geniCodeRValue (right, TRUE);
3493 right = geniCodeRValue (right, FALSE);
3496 geniCodeAssign (left,
3497 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3503 geniCodeAssign (left,
3504 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3506 geniCodeRValue (right, FALSE)), 0);
3509 geniCodeAssign (left,
3510 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3512 geniCodeRValue (right, FALSE)), 0);
3515 geniCodeAssign (left,
3516 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3518 geniCodeRValue (right, FALSE),
3520 operandType (left)), 0);
3523 geniCodeAssign (left,
3524 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3526 geniCodeRValue (right, FALSE),
3528 operandType (left)), 0);
3531 geniCodeAssign (left,
3532 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3534 geniCodeRValue (right, FALSE),
3536 operandType (left)), 0);
3538 return geniCodeRValue (right, FALSE);
3541 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3544 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3545 return ast2iCode (tree->right,lvl+1);
3548 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3549 return ast2iCode (tree->right,lvl+1);
3552 geniCodeFunctionBody (tree,lvl);
3556 geniCodeReturn (right);
3560 geniCodeIfx (tree,lvl);
3564 geniCodeSwitch (tree,lvl);
3568 geniCodeInline (tree);
3572 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3579 /*-----------------------------------------------------------------*/
3580 /* reverseICChain - gets from the list and creates a linkedlist */
3581 /*-----------------------------------------------------------------*/
3588 while ((loop = getSet (&iCodeChain)))
3600 /*-----------------------------------------------------------------*/
3601 /* iCodeFromAst - given an ast will convert it to iCode */
3602 /*-----------------------------------------------------------------*/
3604 iCodeFromAst (ast * tree)
3606 returnLabel = newiTempLabel ("_return");
3607 entryLabel = newiTempLabel ("_entry");
3609 return reverseiCChain ();