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 retval = operandFromValue (valCastLiteral (type,
932 operandLitValue (left) +
933 operandLitValue (right)));
936 retval = operandFromValue (valCastLiteral (type,
937 operandLitValue (left) -
938 operandLitValue (right)));
941 retval = operandFromValue (valCastLiteral (type,
942 operandLitValue (left) *
943 operandLitValue (right)));
946 if ((unsigned long) operandLitValue (right) == 0)
948 werror (E_DIVIDE_BY_ZERO);
953 retval = operandFromValue (valCastLiteral (type,
954 operandLitValue (left) /
955 operandLitValue (right)));
958 if ((unsigned long) operandLitValue (right) == 0) {
959 werror (E_DIVIDE_BY_ZERO);
963 retval = operandFromLit ((SPEC_USIGN(let) ?
964 (unsigned long) operandLitValue (left) :
965 (long) operandLitValue (left)) %
967 (unsigned long) operandLitValue (right) :
968 (long) operandLitValue (right)));
972 retval = operandFromLit ((SPEC_USIGN(let) ?
973 (unsigned long) operandLitValue (left) :
974 (long) operandLitValue (left)) <<
976 (unsigned long) operandLitValue (right) :
977 (long) operandLitValue (right)));
980 retval = operandFromLit ((SPEC_USIGN(let) ?
981 (unsigned long) operandLitValue (left) :
982 (long) operandLitValue (left)) >>
984 (unsigned long) operandLitValue (right) :
985 (long) 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 (operandLitValue (left) >=
1009 operandLitValue (right));
1012 retval = operandFromLit ((long)operandLitValue(left) &
1013 (long)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 (operandLitValue (left) &&
1025 operandLitValue (right));
1028 retval = operandFromLit (operandLitValue (left) ||
1029 operandLitValue (right));
1033 long i = (long) operandLitValue (left);
1035 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1041 long i = (long) operandLitValue (left);
1043 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1049 retval = operandFromLit (-1 * operandLitValue (left));
1053 retval = operandFromLit (~((long) operandLitValue (left)));
1057 retval = operandFromLit (!operandLitValue (left));
1061 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1062 " operandOperation invalid operator ");
1070 /*-----------------------------------------------------------------*/
1071 /* isOperandEqual - compares two operand & return 1 if they r = */
1072 /*-----------------------------------------------------------------*/
1074 isOperandEqual (operand * left, operand * right)
1076 /* if the pointers are equal then they are equal */
1080 /* if either of them null then false */
1081 if (!left || !right)
1084 if (left->type != right->type)
1087 if (IS_SYMOP (left) && IS_SYMOP (right))
1088 return left->key == right->key;
1090 /* if types are the same */
1094 return isSymbolEqual (left->operand.symOperand,
1095 right->operand.symOperand);
1097 return (floatFromVal (left->operand.valOperand) ==
1098 floatFromVal (right->operand.valOperand));
1100 if (compareType (left->operand.typeOperand,
1101 right->operand.typeOperand) == 1)
1108 /*-------------------------------------------------------------------*/
1109 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1110 /*-------------------------------------------------------------------*/
1112 isiCodeEqual (iCode * left, iCode * right)
1114 /* if the same pointer */
1118 /* if either of them null */
1119 if (!left || !right)
1122 /* if operand are the same */
1123 if (left->op == right->op)
1126 /* compare all the elements depending on type */
1127 if (left->op != IFX)
1129 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1131 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1137 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1139 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1141 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1150 /*-----------------------------------------------------------------*/
1151 /* newiTempFromOp - create a temp Operand with same attributes */
1152 /*-----------------------------------------------------------------*/
1154 newiTempFromOp (operand * op)
1164 nop = newiTempOperand (operandType (op), TRUE);
1165 nop->isaddr = op->isaddr;
1166 nop->isvolatile = op->isvolatile;
1167 nop->isGlobal = op->isGlobal;
1168 nop->isLiteral = op->isLiteral;
1169 nop->usesDefs = op->usesDefs;
1170 nop->isParm = op->isParm;
1174 /*-----------------------------------------------------------------*/
1175 /* operand from operand - creates an operand holder for the type */
1176 /*-----------------------------------------------------------------*/
1178 operandFromOperand (operand * op)
1184 nop = newOperand ();
1185 nop->type = op->type;
1186 nop->isaddr = op->isaddr;
1188 nop->isvolatile = op->isvolatile;
1189 nop->isGlobal = op->isGlobal;
1190 nop->isLiteral = op->isLiteral;
1191 nop->usesDefs = op->usesDefs;
1192 nop->isParm = op->isParm;
1197 nop->operand.symOperand = op->operand.symOperand;
1200 nop->operand.valOperand = op->operand.valOperand;
1203 nop->operand.typeOperand = op->operand.typeOperand;
1210 /*-----------------------------------------------------------------*/
1211 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1212 /*-----------------------------------------------------------------*/
1214 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1216 operand *nop = operandFromOperand (op);
1218 if (nop->type == SYMBOL)
1220 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1221 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1227 /*-----------------------------------------------------------------*/
1228 /* operandFromSymbol - creates an operand from a symbol */
1229 /*-----------------------------------------------------------------*/
1231 operandFromSymbol (symbol * sym)
1236 /* if the symbol's type is a literal */
1237 /* then it is an enumerator type */
1238 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1239 return operandFromValue (valFromType (sym->etype));
1242 sym->key = ++operandKey;
1244 /* if this an implicit variable, means struct/union */
1245 /* member so just return it */
1246 if (sym->implicit || IS_FUNC (sym->type))
1250 op->operand.symOperand = sym;
1252 op->isvolatile = isOperandVolatile (op, TRUE);
1253 op->isGlobal = isOperandGlobal (op);
1257 /* under the following conditions create a
1258 register equivalent for a local symbol */
1259 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1260 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1261 /* (!TARGET_IS_DS390)) && */
1262 (!(options.model == MODEL_FLAT24)) ) &&
1263 options.stackAuto == 0)
1266 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1267 !IS_FUNC (sym->type) && /* not a function */
1268 !sym->_isparm && /* not a parameter */
1269 sym->level && /* is a local variable */
1270 !sym->addrtaken && /* whose address has not been taken */
1271 !sym->reqv && /* does not already have a register euivalence */
1272 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1273 !IS_STATIC (sym->etype) && /* and not declared static */
1274 !sym->islbl && /* not a label */
1275 ok && /* farspace check */
1276 !IS_BITVAR (sym->etype) /* not a bit variable */
1280 /* we will use it after all optimizations
1281 and before liveRange calculation */
1282 sym->reqv = newiTempOperand (sym->type, 0);
1283 sym->reqv->key = sym->key;
1284 OP_SYMBOL (sym->reqv)->key = sym->key;
1285 OP_SYMBOL (sym->reqv)->isreqv = 1;
1286 OP_SYMBOL (sym->reqv)->islocal = 1;
1287 SPIL_LOC (sym->reqv) = sym;
1290 if (!IS_AGGREGATE (sym->type))
1294 op->operand.symOperand = sym;
1297 op->isvolatile = isOperandVolatile (op, TRUE);
1298 op->isGlobal = isOperandGlobal (op);
1299 op->isPtr = IS_PTR (operandType (op));
1300 op->isParm = sym->_isparm;
1305 /* itemp = &[_symbol] */
1307 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1308 IC_LEFT (ic)->type = SYMBOL;
1309 IC_LEFT (ic)->operand.symOperand = sym;
1310 IC_LEFT (ic)->key = sym->key;
1311 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1312 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1313 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1316 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1317 if (IS_ARRAY (sym->type))
1319 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1320 IC_RESULT (ic)->isaddr = 0;
1323 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1325 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1329 return IC_RESULT (ic);
1332 /*-----------------------------------------------------------------*/
1333 /* operandFromValue - creates an operand from value */
1334 /*-----------------------------------------------------------------*/
1336 operandFromValue (value * val)
1340 /* if this is a symbol then do the symbol thing */
1342 return operandFromSymbol (val->sym);
1344 /* this is not a symbol */
1347 op->operand.valOperand = val;
1348 op->isLiteral = isOperandLiteral (op);
1352 /*-----------------------------------------------------------------*/
1353 /* operandFromLink - operand from typeChain */
1354 /*-----------------------------------------------------------------*/
1356 operandFromLink (sym_link * type)
1360 /* operand from sym_link */
1366 op->operand.typeOperand = copyLinkChain (type);
1370 /*-----------------------------------------------------------------*/
1371 /* operandFromLit - makes an operand from a literal value */
1372 /*-----------------------------------------------------------------*/
1374 operandFromLit (double i)
1376 return operandFromValue (valueFromLit (i));
1379 /*-----------------------------------------------------------------*/
1380 /* operandFromAst - creates an operand from an ast */
1381 /*-----------------------------------------------------------------*/
1383 operandFromAst (ast * tree,int lvl)
1389 /* depending on type do */
1393 return ast2iCode (tree,lvl+1);
1397 return operandFromValue (tree->opval.val);
1401 return operandFromLink (tree->opval.lnk);
1405 /* Just to keep the comiler happy */
1406 return (operand *) 0;
1409 /*-----------------------------------------------------------------*/
1410 /* setOperandType - sets the operand's type to the given type */
1411 /*-----------------------------------------------------------------*/
1413 setOperandType (operand * op, sym_link * type)
1415 /* depending on the type of operand */
1420 op->operand.valOperand->etype =
1421 getSpec (op->operand.valOperand->type =
1422 copyLinkChain (type));
1426 if (op->operand.symOperand->isitmp)
1427 op->operand.symOperand->etype =
1428 getSpec (op->operand.symOperand->type =
1429 copyLinkChain (type));
1431 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1432 "attempt to modify type of source");
1436 op->operand.typeOperand = copyLinkChain (type);
1441 /*-----------------------------------------------------------------*/
1442 /* Get size in byte of ptr need to access an array */
1443 /*-----------------------------------------------------------------*/
1445 getArraySizePtr (operand * op)
1447 sym_link *ltype = operandType(op);
1451 int size = getSize(ltype);
1452 return(IS_GENPTR(ltype)?(size-1):size);
1457 sym_link *letype = getSpec(ltype);
1458 switch (PTR_TYPE (SPEC_OCLS (letype)))
1470 return (GPTRSIZE-1);
1479 /*-----------------------------------------------------------------*/
1480 /* perform "usual unary conversions" */
1481 /*-----------------------------------------------------------------*/
1483 usualUnaryConversions (operand * op)
1485 if (IS_INTEGRAL (operandType (op)))
1487 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1490 return geniCodeCast (INTTYPE, op, TRUE);
1496 /*-----------------------------------------------------------------*/
1497 /* perform "usual binary conversions" */
1498 /*-----------------------------------------------------------------*/
1500 usualBinaryConversions (operand ** op1, operand ** op2)
1503 sym_link *rtype = operandType (*op2);
1504 sym_link *ltype = operandType (*op1);
1506 ctype = computeType (ltype, rtype);
1507 *op1 = geniCodeCast (ctype, *op1, TRUE);
1508 *op2 = geniCodeCast (ctype, *op2, TRUE);
1513 /*-----------------------------------------------------------------*/
1514 /* geniCodeValueAtAddress - generate intermeditate code for value */
1516 /*-----------------------------------------------------------------*/
1518 geniCodeRValue (operand * op, bool force)
1521 sym_link *type = operandType (op);
1522 sym_link *etype = getSpec (type);
1524 /* if this is an array & already */
1525 /* an address then return this */
1526 if (IS_AGGREGATE (type) ||
1527 (IS_PTR (type) && !force && !op->isaddr))
1528 return operandFromOperand (op);
1530 /* if this is not an address then must be */
1531 /* rvalue already so return this one */
1535 /* if this is not a temp symbol then */
1536 if (!IS_ITEMP (op) &&
1538 !IN_FARSPACE (SPEC_OCLS (etype)))
1540 op = operandFromOperand (op);
1545 if (IS_SPEC (type) &&
1546 IS_TRUE_SYMOP (op) &&
1547 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1548 /* TARGET_IS_DS390)) */
1549 (options.model == MODEL_FLAT24) ))
1551 op = operandFromOperand (op);
1556 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1557 if (IS_PTR (type) && op->isaddr && force)
1560 type = copyLinkChain (type);
1562 IC_RESULT (ic) = newiTempOperand (type, 1);
1563 IC_RESULT (ic)->isaddr = 0;
1565 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1567 /* if the right is a symbol */
1568 if (op->type == SYMBOL)
1569 IC_RESULT (ic)->operand.symOperand->args =
1570 op->operand.symOperand->args;
1573 return IC_RESULT (ic);
1576 /*-----------------------------------------------------------------*/
1577 /* geniCodeCast - changes the value from one type to another */
1578 /*-----------------------------------------------------------------*/
1580 geniCodeCast (sym_link * type, operand * op, bool implicit)
1584 sym_link *opetype = getSpec (optype = operandType (op));
1588 /* one of them has size zero then error */
1589 if (IS_VOID (optype))
1591 werror (E_CAST_ZERO);
1595 /* if the operand is already the desired type then do nothing */
1596 if (compareType (type, optype) == 1)
1599 /* if this is a literal then just change the type & return */
1600 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1601 return operandFromValue (valCastLiteral (type,
1602 operandLitValue (op)));
1604 /* if casting to/from pointers, do some checking */
1605 if (IS_PTR(type)) { // to a pointer
1606 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1607 if (IS_INTEGRAL(optype)) {
1608 // maybe this is NULL, than it's ok.
1609 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1610 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1611 // no way to set the storage
1612 if (IS_LITERAL(optype)) {
1613 werror(E_LITERAL_GENERIC);
1616 werror(E_NONPTR2_GENPTR);
1619 } else if (implicit) {
1620 werror(W_INTEGRAL2PTR_NOCAST);
1625 // shouldn't do that with float, array or structure unless to void
1626 if (!IS_VOID(getSpec(type)) &&
1627 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1628 werror(E_INCOMPAT_TYPES);
1632 } else { // from a pointer to a pointer
1633 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1634 // if not a pointer to a function
1635 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1636 if (implicit) { // if not to generic, they have to match
1637 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1638 werror(E_INCOMPAT_PTYPES);
1645 } else { // to a non pointer
1646 if (IS_PTR(optype)) { // from a pointer
1647 if (implicit) { // sneaky
1648 if (IS_INTEGRAL(type)) {
1649 werror(W_PTR2INTEGRAL_NOCAST);
1651 } else { // shouldn't do that with float, array or structure
1652 werror(E_INCOMPAT_TYPES);
1659 /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
1660 implicit?"(implicit)":"", errors); */
1661 fprintf (stderr, "from type '");
1662 printTypeChain (optype, stderr);
1663 fprintf (stderr, "' to type '");
1664 printTypeChain (type, stderr);
1665 fprintf (stderr, "'\n");
1668 /* if they are the same size create an assignment */
1669 if (getSize (type) == getSize (optype) &&
1670 !IS_BITFIELD (type) &&
1672 !IS_FLOAT (optype) &&
1673 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1674 (!IS_SPEC (type) && !IS_SPEC (optype))))
1677 ic = newiCode ('=', NULL, op);
1678 IC_RESULT (ic) = newiTempOperand (type, 0);
1679 SPIL_LOC (IC_RESULT (ic)) =
1680 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1681 IC_RESULT (ic)->isaddr = 0;
1685 ic = newiCode (CAST, operandFromLink (type),
1686 geniCodeRValue (op, FALSE));
1688 IC_RESULT (ic) = newiTempOperand (type, 0);
1691 /* preserve the storage class & output class */
1692 /* of the original variable */
1693 restype = getSpec (operandType (IC_RESULT (ic)));
1694 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1695 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1698 return IC_RESULT (ic);
1701 /*-----------------------------------------------------------------*/
1702 /* geniCodeLabel - will create a Label */
1703 /*-----------------------------------------------------------------*/
1705 geniCodeLabel (symbol * label)
1709 ic = newiCodeLabelGoto (LABEL, label);
1713 /*-----------------------------------------------------------------*/
1714 /* geniCodeGoto - will create a Goto */
1715 /*-----------------------------------------------------------------*/
1717 geniCodeGoto (symbol * label)
1721 ic = newiCodeLabelGoto (GOTO, label);
1725 /*-----------------------------------------------------------------*/
1726 /* geniCodeMultiply - gen intermediate code for multiplication */
1727 /*-----------------------------------------------------------------*/
1729 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1736 /* if they are both literal then we know the result */
1737 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1738 return operandFromValue (valMult (left->operand.valOperand,
1739 right->operand.valOperand));
1741 if (IS_LITERAL(retype)) {
1742 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1745 resType = usualBinaryConversions (&left, &right);
1747 rtype = operandType (right);
1748 retype = getSpec (rtype);
1749 ltype = operandType (left);
1750 letype = getSpec (ltype);
1754 SPEC_NOUN(getSpec(resType))=V_INT;
1757 /* if the right is a literal & power of 2 */
1758 /* then make it a left shift */
1759 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1760 efficient in most cases than 2 bytes result = 2 bytes << literal
1761 if port has 1 byte muldiv */
1762 if (p2 && !IS_FLOAT (letype) &&
1763 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1764 (port->support.muldiv == 1)))
1766 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1768 /* LEFT_OP need same size for left and result, */
1769 left = geniCodeCast (resType, left, TRUE);
1770 ltype = operandType (left);
1772 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1776 ic = newiCode ('*', left, right); /* normal multiplication */
1777 /* if the size left or right > 1 then support routine */
1778 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1782 IC_RESULT (ic) = newiTempOperand (resType, 1);
1785 return IC_RESULT (ic);
1788 /*-----------------------------------------------------------------*/
1789 /* geniCodeDivision - gen intermediate code for division */
1790 /*-----------------------------------------------------------------*/
1792 geniCodeDivision (operand * left, operand * right)
1797 sym_link *rtype = operandType (right);
1798 sym_link *retype = getSpec (rtype);
1799 sym_link *ltype = operandType (left);
1800 sym_link *letype = getSpec (ltype);
1802 resType = usualBinaryConversions (&left, &right);
1804 /* if the right is a literal & power of 2 */
1805 /* then make it a right shift */
1806 if (IS_LITERAL (retype) &&
1807 !IS_FLOAT (letype) &&
1808 (p2 = powof2 ((unsigned long)
1809 floatFromVal (right->operand.valOperand)))) {
1810 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1814 ic = newiCode ('/', left, right); /* normal division */
1815 /* if the size left or right > 1 then support routine */
1816 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1819 IC_RESULT (ic) = newiTempOperand (resType, 0);
1822 return IC_RESULT (ic);
1824 /*-----------------------------------------------------------------*/
1825 /* geniCodeModulus - gen intermediate code for modulus */
1826 /*-----------------------------------------------------------------*/
1828 geniCodeModulus (operand * left, operand * right)
1834 /* if they are both literal then we know the result */
1835 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1836 return operandFromValue (valMod (left->operand.valOperand,
1837 right->operand.valOperand));
1839 resType = usualBinaryConversions (&left, &right);
1841 /* now they are the same size */
1842 ic = newiCode ('%', left, right);
1844 /* if the size left or right > 1 then support routine */
1845 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1847 IC_RESULT (ic) = newiTempOperand (resType, 0);
1850 return IC_RESULT (ic);
1853 /*-----------------------------------------------------------------*/
1854 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1855 /*-----------------------------------------------------------------*/
1857 geniCodePtrPtrSubtract (operand * left, operand * right)
1863 /* if they are both literals then */
1864 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1866 result = operandFromValue (valMinus (left->operand.valOperand,
1867 right->operand.valOperand));
1871 ic = newiCode ('-', left, right);
1873 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1877 return geniCodeDivision (result,
1878 operandFromLit (getSize (ltype->next)));
1881 /*-----------------------------------------------------------------*/
1882 /* geniCodeSubtract - generates code for subtraction */
1883 /*-----------------------------------------------------------------*/
1885 geniCodeSubtract (operand * left, operand * right)
1892 /* if they both pointers then */
1893 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1894 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1895 return geniCodePtrPtrSubtract (left, right);
1897 /* if they are both literal then we know the result */
1898 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1899 && left->isLiteral && right->isLiteral)
1900 return operandFromValue (valMinus (left->operand.valOperand,
1901 right->operand.valOperand));
1903 /* if left is an array or pointer */
1904 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1906 isarray = left->isaddr;
1907 right = geniCodeMultiply (right,
1908 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1909 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1912 { /* make them the same size */
1913 resType = usualBinaryConversions (&left, &right);
1916 ic = newiCode ('-', left, right);
1918 IC_RESULT (ic) = newiTempOperand (resType, 1);
1919 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1921 /* if left or right is a float */
1922 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1926 return IC_RESULT (ic);
1929 /*-----------------------------------------------------------------*/
1930 /* geniCodeAdd - generates iCode for addition */
1931 /*-----------------------------------------------------------------*/
1933 geniCodeAdd (operand * left, operand * right,int lvl)
1941 /* if left is an array then array access */
1942 if (IS_ARRAY (ltype))
1943 return geniCodeArray (left, right,lvl);
1945 /* if the right side is LITERAL zero */
1946 /* return the left side */
1947 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1950 /* if left is literal zero return right */
1951 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1954 /* if left is an array or pointer then size */
1957 isarray = left->isaddr;
1958 // there is no need to multiply with 1
1959 if (getSize(ltype->next)!=1) {
1960 size = operandFromLit (getSize (ltype->next));
1961 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1963 resType = copyLinkChain (ltype);
1966 { /* make them the same size */
1967 resType = usualBinaryConversions (&left, &right);
1970 /* if they are both literals then we know */
1971 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1972 && left->isLiteral && right->isLiteral)
1973 return operandFromValue (valPlus (valFromType (letype),
1974 valFromType (retype)));
1976 ic = newiCode ('+', left, right);
1978 IC_RESULT (ic) = newiTempOperand (resType, 1);
1979 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1981 /* if left or right is a float then support
1983 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1988 return IC_RESULT (ic);
1992 /*-----------------------------------------------------------------*/
1993 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1994 /*-----------------------------------------------------------------*/
1996 aggrToPtr (sym_link * type, bool force)
2002 if (IS_PTR (type) && !force)
2005 etype = getSpec (type);
2009 /* if the output class is generic */
2010 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2011 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2013 /* if the variable was declared a constant */
2014 /* then the pointer points to a constant */
2015 if (IS_CONSTANT (etype))
2016 DCL_PTR_CONST (ptype) = 1;
2018 /* the variable was volatile then pointer to volatile */
2019 if (IS_VOLATILE (etype))
2020 DCL_PTR_VOLATILE (ptype) = 1;
2024 /*-----------------------------------------------------------------*/
2025 /* geniCodeArray2Ptr - array to pointer */
2026 /*-----------------------------------------------------------------*/
2028 geniCodeArray2Ptr (operand * op)
2030 sym_link *optype = operandType (op);
2031 sym_link *opetype = getSpec (optype);
2033 /* set the pointer depending on the storage class */
2034 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2035 DCL_PTR_CONST (optype) = port->mem.code_ro;
2038 /* if the variable was declared a constant */
2039 /* then the pointer points to a constant */
2040 if (IS_CONSTANT (opetype))
2041 DCL_PTR_CONST (optype) = 1;
2043 /* the variable was volatile then pointer to volatile */
2044 if (IS_VOLATILE (opetype))
2045 DCL_PTR_VOLATILE (optype) = 1;
2051 /*-----------------------------------------------------------------*/
2052 /* geniCodeArray - array access */
2053 /*-----------------------------------------------------------------*/
2055 geniCodeArray (operand * left, operand * right,int lvl)
2058 sym_link *ltype = operandType (left);
2062 if (IS_PTR (ltype->next) && left->isaddr)
2064 left = geniCodeRValue (left, FALSE);
2066 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2069 right = geniCodeMultiply (right,
2070 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2072 /* we can check for limits here */
2073 if (isOperandLiteral (right) &&
2076 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2078 werror (E_ARRAY_BOUND);
2079 right = operandFromLit (0);
2082 ic = newiCode ('+', left, right);
2084 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2085 !IS_AGGREGATE (ltype->next) &&
2086 !IS_PTR (ltype->next))
2087 ? ltype : ltype->next), 0);
2089 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2091 return IC_RESULT (ic);
2094 /*-----------------------------------------------------------------*/
2095 /* geniCodeStruct - generates intermediate code for structres */
2096 /*-----------------------------------------------------------------*/
2098 geniCodeStruct (operand * left, operand * right, bool islval)
2101 sym_link *type = operandType (left);
2102 sym_link *etype = getSpec (type);
2104 symbol *element = getStructElement (SPEC_STRUCT (etype),
2105 right->operand.symOperand);
2107 /* add the offset */
2108 ic = newiCode ('+', left, operandFromLit (element->offset));
2110 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2112 /* preserve the storage & output class of the struct */
2113 /* as well as the volatile attribute */
2114 retype = getSpec (operandType (IC_RESULT (ic)));
2115 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2116 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2117 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2119 if (IS_PTR (element->type))
2120 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2122 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2126 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2129 /*-----------------------------------------------------------------*/
2130 /* geniCodePostInc - generate int code for Post increment */
2131 /*-----------------------------------------------------------------*/
2133 geniCodePostInc (operand * op)
2137 sym_link *optype = operandType (op);
2139 operand *rv = (IS_ITEMP (op) ?
2140 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2142 sym_link *rvtype = operandType (rv);
2145 /* if this is not an address we have trouble */
2148 werror (E_LVALUE_REQUIRED, "++");
2152 rOp = newiTempOperand (rvtype, 0);
2153 OP_SYMBOL(rOp)->noSpilLoc = 1;
2156 OP_SYMBOL(rv)->noSpilLoc = 1;
2158 geniCodeAssign (rOp, rv, 0);
2160 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2161 if (IS_FLOAT (rvtype))
2162 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2164 ic = newiCode ('+', rv, operandFromLit (size));
2166 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2169 geniCodeAssign (op, result, 0);
2175 /*-----------------------------------------------------------------*/
2176 /* geniCodePreInc - generate code for preIncrement */
2177 /*-----------------------------------------------------------------*/
2179 geniCodePreInc (operand * op)
2182 sym_link *optype = operandType (op);
2183 operand *rop = (IS_ITEMP (op) ?
2184 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2186 sym_link *roptype = operandType (rop);
2192 werror (E_LVALUE_REQUIRED, "++");
2197 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2198 if (IS_FLOAT (roptype))
2199 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2201 ic = newiCode ('+', rop, operandFromLit (size));
2202 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2206 return geniCodeAssign (op, result, 0);
2209 /*-----------------------------------------------------------------*/
2210 /* geniCodePostDec - generates code for Post decrement */
2211 /*-----------------------------------------------------------------*/
2213 geniCodePostDec (operand * op)
2217 sym_link *optype = operandType (op);
2219 operand *rv = (IS_ITEMP (op) ?
2220 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2222 sym_link *rvtype = operandType (rv);
2225 /* if this is not an address we have trouble */
2228 werror (E_LVALUE_REQUIRED, "--");
2232 rOp = newiTempOperand (rvtype, 0);
2233 OP_SYMBOL(rOp)->noSpilLoc = 1;
2236 OP_SYMBOL(rv)->noSpilLoc = 1;
2238 geniCodeAssign (rOp, rv, 0);
2240 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2241 if (IS_FLOAT (rvtype))
2242 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2244 ic = newiCode ('-', rv, operandFromLit (size));
2246 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2249 geniCodeAssign (op, result, 0);
2255 /*-----------------------------------------------------------------*/
2256 /* geniCodePreDec - generate code for pre decrement */
2257 /*-----------------------------------------------------------------*/
2259 geniCodePreDec (operand * op)
2262 sym_link *optype = operandType (op);
2263 operand *rop = (IS_ITEMP (op) ?
2264 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2266 sym_link *roptype = operandType (rop);
2272 werror (E_LVALUE_REQUIRED, "--");
2277 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2278 if (IS_FLOAT (roptype))
2279 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2281 ic = newiCode ('-', rop, operandFromLit (size));
2282 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2286 return geniCodeAssign (op, result, 0);
2290 /*-----------------------------------------------------------------*/
2291 /* geniCodeBitwise - gen int code for bitWise operators */
2292 /*-----------------------------------------------------------------*/
2294 geniCodeBitwise (operand * left, operand * right,
2295 int oper, sym_link * resType)
2299 left = geniCodeCast (resType, left, TRUE);
2300 right = geniCodeCast (resType, right, TRUE);
2302 ic = newiCode (oper, left, right);
2303 IC_RESULT (ic) = newiTempOperand (resType, 0);
2306 return IC_RESULT (ic);
2309 /*-----------------------------------------------------------------*/
2310 /* geniCodeAddressOf - gens icode for '&' address of operator */
2311 /*-----------------------------------------------------------------*/
2313 geniCodeAddressOf (operand * op)
2317 sym_link *optype = operandType (op);
2318 sym_link *opetype = getSpec (optype);
2320 /* lvalue check already done in decorateType */
2321 /* this must be a lvalue */
2322 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2323 /* werror (E_LVALUE_REQUIRED,"&"); */
2328 p->class = DECLARATOR;
2330 /* set the pointer depending on the storage class */
2331 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2332 DCL_PTR_CONST (p) = port->mem.code_ro;
2334 /* make sure we preserve the const & volatile */
2335 if (IS_CONSTANT (opetype))
2336 DCL_PTR_CONST (p) = 1;
2338 if (IS_VOLATILE (opetype))
2339 DCL_PTR_VOLATILE (p) = 1;
2341 p->next = copyLinkChain (optype);
2343 /* if already a temp */
2346 setOperandType (op, p);
2351 /* other wise make this of the type coming in */
2352 ic = newiCode (ADDRESS_OF, op, NULL);
2353 IC_RESULT (ic) = newiTempOperand (p, 1);
2354 IC_RESULT (ic)->isaddr = 0;
2356 return IC_RESULT (ic);
2358 /*-----------------------------------------------------------------*/
2359 /* setOClass - sets the output class depending on the pointer type */
2360 /*-----------------------------------------------------------------*/
2362 setOClass (sym_link * ptr, sym_link * spec)
2364 switch (DCL_TYPE (ptr))
2367 SPEC_OCLS (spec) = data;
2371 SPEC_OCLS (spec) = generic;
2375 SPEC_OCLS (spec) = xdata;
2379 SPEC_OCLS (spec) = code;
2383 SPEC_OCLS (spec) = idata;
2387 SPEC_OCLS (spec) = xstack;
2391 SPEC_OCLS (spec) = eeprom;
2400 /*-----------------------------------------------------------------*/
2401 /* geniCodeDerefPtr - dereference pointer with '*' */
2402 /*-----------------------------------------------------------------*/
2404 geniCodeDerefPtr (operand * op,int lvl)
2406 sym_link *rtype, *retype;
2407 sym_link *optype = operandType (op);
2409 /* if this is a pointer then generate the rvalue */
2410 if (IS_PTR (optype))
2412 if (IS_TRUE_SYMOP (op))
2415 op = geniCodeRValue (op, TRUE);
2418 op = geniCodeRValue (op, TRUE);
2421 /* now get rid of the pointer part */
2422 if (isLvaluereq(lvl) && IS_ITEMP (op))
2424 retype = getSpec (rtype = copyLinkChain (optype));
2428 retype = getSpec (rtype = copyLinkChain (optype->next));
2431 /* if this is a pointer then outputclass needs 2b updated */
2432 if (IS_PTR (optype))
2433 setOClass (optype, retype);
2435 op->isGptr = IS_GENPTR (optype);
2437 /* if the pointer was declared as a constant */
2438 /* then we cannot allow assignment to the derefed */
2439 if (IS_PTR_CONST (optype))
2440 SPEC_CONST (retype) = 1;
2442 op->isaddr = (IS_PTR (rtype) ||
2443 IS_STRUCT (rtype) ||
2448 if (!isLvaluereq(lvl))
2449 op = geniCodeRValue (op, TRUE);
2451 setOperandType (op, rtype);
2456 /*-----------------------------------------------------------------*/
2457 /* geniCodeUnaryMinus - does a unary minus of the operand */
2458 /*-----------------------------------------------------------------*/
2460 geniCodeUnaryMinus (operand * op)
2463 sym_link *optype = operandType (op);
2465 if (IS_LITERAL (optype))
2466 return operandFromLit (-floatFromVal (op->operand.valOperand));
2468 ic = newiCode (UNARYMINUS, op, NULL);
2469 IC_RESULT (ic) = newiTempOperand (optype, 0);
2471 return IC_RESULT (ic);
2474 /*-----------------------------------------------------------------*/
2475 /* geniCodeLeftShift - gen i code for left shift */
2476 /*-----------------------------------------------------------------*/
2478 geniCodeLeftShift (operand * left, operand * right)
2482 ic = newiCode (LEFT_OP, left, right);
2483 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2485 return IC_RESULT (ic);
2488 /*-----------------------------------------------------------------*/
2489 /* geniCodeRightShift - gen i code for right shift */
2490 /*-----------------------------------------------------------------*/
2492 geniCodeRightShift (operand * left, operand * right)
2496 ic = newiCode (RIGHT_OP, left, right);
2497 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2499 return IC_RESULT (ic);
2502 /*-----------------------------------------------------------------*/
2503 /* geniCodeLogic- logic code */
2504 /*-----------------------------------------------------------------*/
2506 geniCodeLogic (operand * left, operand * right, int op)
2510 sym_link *rtype = operandType (right);
2511 sym_link *ltype = operandType (left);
2513 /* left is integral type and right is literal then
2514 check if the literal value is within bounds */
2515 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2517 checkConstantRange(ltype,
2518 OP_VALUE(right), "compare operation", 1);
2521 ctype = usualBinaryConversions (&left, &right);
2523 ic = newiCode (op, left, right);
2524 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2526 /* if comparing float
2527 and not a '==' || '!=' || '&&' || '||' (these
2529 if (IS_FLOAT(ctype) &&
2537 return IC_RESULT (ic);
2540 /*-----------------------------------------------------------------*/
2541 /* geniCodeUnary - for a a generic unary operation */
2542 /*-----------------------------------------------------------------*/
2544 geniCodeUnary (operand * op, int oper)
2546 iCode *ic = newiCode (oper, op, NULL);
2548 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2550 return IC_RESULT (ic);
2553 /*-----------------------------------------------------------------*/
2554 /* geniCodeConditional - geniCode for '?' ':' operation */
2555 /*-----------------------------------------------------------------*/
2557 geniCodeConditional (ast * tree,int lvl)
2560 symbol *falseLabel = newiTempLabel (NULL);
2561 symbol *exitLabel = newiTempLabel (NULL);
2562 operand *cond = ast2iCode (tree->left,lvl+1);
2563 operand *true, *false, *result;
2565 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2569 true = ast2iCode (tree->right->left,lvl+1);
2571 /* move the value to a new Operand */
2572 result = newiTempOperand (operandType (true), 0);
2573 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2575 /* generate an unconditional goto */
2576 geniCodeGoto (exitLabel);
2578 /* now for the right side */
2579 geniCodeLabel (falseLabel);
2581 false = ast2iCode (tree->right->right,lvl+1);
2582 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2584 /* create the exit label */
2585 geniCodeLabel (exitLabel);
2590 /*-----------------------------------------------------------------*/
2591 /* geniCodeAssign - generate code for assignment */
2592 /*-----------------------------------------------------------------*/
2594 geniCodeAssign (operand * left, operand * right, int nosupdate)
2597 sym_link *ltype = operandType (left);
2598 sym_link *rtype = operandType (right);
2600 if (!left->isaddr && !IS_ITEMP (left))
2602 werror (E_LVALUE_REQUIRED, "assignment");
2606 /* left is integral type and right is literal then
2607 check if the literal value is within bounds */
2608 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2610 checkConstantRange(ltype,
2611 OP_VALUE(right), "= operation", 0);
2614 /* if the left & right type don't exactly match */
2615 /* if pointer set then make sure the check is
2616 done with the type & not the pointer */
2617 /* then cast rights type to left */
2619 /* first check the type for pointer assignement */
2620 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2621 compareType (ltype, rtype) < 0)
2623 if (compareType (ltype->next, rtype) < 0)
2624 right = geniCodeCast (ltype->next, right, TRUE);
2626 else if (compareType (ltype, rtype) < 0)
2627 right = geniCodeCast (ltype, right, TRUE);
2629 /* if left is a true symbol & ! volatile
2630 create an assignment to temporary for
2631 the right & then assign this temporary
2632 to the symbol this is SSA . isn't it simple
2633 and folks have published mountains of paper on it */
2634 if (IS_TRUE_SYMOP (left) &&
2635 !isOperandVolatile (left, FALSE) &&
2636 isOperandGlobal (left))
2640 if (IS_TRUE_SYMOP (right))
2641 sym = OP_SYMBOL (right);
2642 ic = newiCode ('=', NULL, right);
2643 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2644 SPIL_LOC (right) = sym;
2648 ic = newiCode ('=', NULL, right);
2649 IC_RESULT (ic) = left;
2652 /* if left isgptr flag is set then support
2653 routine will be required */
2657 ic->nosupdate = nosupdate;
2661 /*-----------------------------------------------------------------*/
2662 /* geniCodeSEParms - generate code for side effecting fcalls */
2663 /*-----------------------------------------------------------------*/
2665 geniCodeSEParms (ast * parms,int lvl)
2670 if (parms->type == EX_OP && parms->opval.op == PARAM)
2672 geniCodeSEParms (parms->left,lvl);
2673 geniCodeSEParms (parms->right,lvl);
2677 /* hack don't like this but too lazy to think of
2679 if (IS_ADDRESS_OF_OP (parms))
2680 parms->left->lvalue = 1;
2682 if (IS_CAST_OP (parms) &&
2683 IS_PTR (parms->ftype) &&
2684 IS_ADDRESS_OF_OP (parms->right))
2685 parms->right->left->lvalue = 1;
2687 parms->opval.oprnd =
2688 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2690 parms->type = EX_OPERAND;
2693 /*-----------------------------------------------------------------*/
2694 /* geniCodeParms - generates parameters */
2695 /*-----------------------------------------------------------------*/
2697 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2705 /* if this is a param node then do the left & right */
2706 if (parms->type == EX_OP && parms->opval.op == PARAM)
2708 geniCodeParms (parms->left, stack, fetype, func,lvl);
2709 geniCodeParms (parms->right, stack, fetype, func,lvl);
2713 /* get the parameter value */
2714 if (parms->type == EX_OPERAND)
2715 pval = parms->opval.oprnd;
2718 /* maybe this else should go away ?? */
2719 /* hack don't like this but too lazy to think of
2721 if (IS_ADDRESS_OF_OP (parms))
2722 parms->left->lvalue = 1;
2724 if (IS_CAST_OP (parms) &&
2725 IS_PTR (parms->ftype) &&
2726 IS_ADDRESS_OF_OP (parms->right))
2727 parms->right->left->lvalue = 1;
2729 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2732 /* if register parm then make it a send */
2733 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2734 IS_REGPARM (parms->etype)) && !func->hasVargs)
2736 ic = newiCode (SEND, pval, NULL);
2741 /* now decide whether to push or assign */
2742 if (!(options.stackAuto || IS_RENT (fetype)))
2746 operand *top = operandFromSymbol (parms->argSym);
2747 geniCodeAssign (top, pval, 1);
2751 sym_link *p = operandType (pval);
2753 ic = newiCode (IPUSH, pval, NULL);
2755 /* update the stack adjustment */
2756 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2763 /*-----------------------------------------------------------------*/
2764 /* geniCodeCall - generates temp code for calling */
2765 /*-----------------------------------------------------------------*/
2767 geniCodeCall (operand * left, ast * parms,int lvl)
2771 sym_link *type, *etype;
2774 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2775 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2776 werror (E_FUNCTION_EXPECTED);
2780 /* take care of parameters with side-effecting
2781 function calls in them, this is required to take care
2782 of overlaying function parameters */
2783 geniCodeSEParms (parms,lvl);
2785 /* first the parameters */
2786 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2788 /* now call : if symbol then pcall */
2789 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2790 ic = newiCode (PCALL, left, NULL);
2792 ic = newiCode (CALL, left, NULL);
2794 IC_ARGS (ic) = left->operand.symOperand->args;
2795 type = copyLinkChain (operandType (left)->next);
2796 etype = getSpec (type);
2797 SPEC_EXTR (etype) = 0;
2798 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2802 /* stack adjustment after call */
2803 ic->parmBytes = stack;
2808 /*-----------------------------------------------------------------*/
2809 /* geniCodeReceive - generate intermediate code for "receive" */
2810 /*-----------------------------------------------------------------*/
2812 geniCodeReceive (value * args)
2814 /* for all arguments that are passed in registers */
2818 if (IS_REGPARM (args->etype))
2820 operand *opr = operandFromValue (args);
2822 symbol *sym = OP_SYMBOL (opr);
2825 /* we will use it after all optimizations
2826 and before liveRange calculation */
2827 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2830 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2831 options.stackAuto == 0 &&
2832 /* !TARGET_IS_DS390) */
2833 (!(options.model == MODEL_FLAT24)) )
2838 opl = newiTempOperand (args->type, 0);
2840 sym->reqv->key = sym->key;
2841 OP_SYMBOL (sym->reqv)->key = sym->key;
2842 OP_SYMBOL (sym->reqv)->isreqv = 1;
2843 OP_SYMBOL (sym->reqv)->islocal = 0;
2844 SPIL_LOC (sym->reqv) = sym;
2848 ic = newiCode (RECEIVE, NULL, NULL);
2849 currFunc->recvSize = getSize (sym->etype);
2850 IC_RESULT (ic) = opr;
2858 /*-----------------------------------------------------------------*/
2859 /* geniCodeFunctionBody - create the function body */
2860 /*-----------------------------------------------------------------*/
2862 geniCodeFunctionBody (ast * tree,int lvl)
2869 /* reset the auto generation */
2875 func = ast2iCode (tree->left,lvl+1);
2876 fetype = getSpec (operandType (func));
2878 savelineno = lineno;
2879 lineno = OP_SYMBOL (func)->lineDef;
2880 /* create an entry label */
2881 geniCodeLabel (entryLabel);
2882 lineno = savelineno;
2884 /* create a proc icode */
2885 ic = newiCode (FUNCTION, func, NULL);
2886 /* if the function has parmas then */
2887 /* save the parameters information */
2888 ic->argLabel.args = tree->values.args;
2889 ic->lineno = OP_SYMBOL (func)->lineDef;
2893 /* for all parameters that are passed
2894 on registers add a "receive" */
2895 geniCodeReceive (tree->values.args);
2897 /* generate code for the body */
2898 ast2iCode (tree->right,lvl+1);
2900 /* create a label for return */
2901 geniCodeLabel (returnLabel);
2903 /* now generate the end proc */
2904 ic = newiCode (ENDFUNCTION, func, NULL);
2909 /*-----------------------------------------------------------------*/
2910 /* geniCodeReturn - gen icode for 'return' statement */
2911 /*-----------------------------------------------------------------*/
2913 geniCodeReturn (operand * op)
2917 /* if the operand is present force an rvalue */
2919 op = geniCodeRValue (op, FALSE);
2921 ic = newiCode (RETURN, op, NULL);
2925 /*-----------------------------------------------------------------*/
2926 /* geniCodeIfx - generates code for extended if statement */
2927 /*-----------------------------------------------------------------*/
2929 geniCodeIfx (ast * tree,int lvl)
2932 operand *condition = ast2iCode (tree->left,lvl+1);
2935 /* if condition is null then exit */
2939 condition = geniCodeRValue (condition, FALSE);
2941 cetype = getSpec (operandType (condition));
2942 /* if the condition is a literal */
2943 if (IS_LITERAL (cetype))
2945 if (floatFromVal (condition->operand.valOperand))
2947 if (tree->trueLabel)
2948 geniCodeGoto (tree->trueLabel);
2954 if (tree->falseLabel)
2955 geniCodeGoto (tree->falseLabel);
2962 if (tree->trueLabel)
2964 ic = newiCodeCondition (condition,
2969 if (tree->falseLabel)
2970 geniCodeGoto (tree->falseLabel);
2974 ic = newiCodeCondition (condition,
2981 ast2iCode (tree->right,lvl+1);
2984 /*-----------------------------------------------------------------*/
2985 /* geniCodeJumpTable - tries to create a jump table for switch */
2986 /*-----------------------------------------------------------------*/
2988 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2990 int min = 0, max = 0, t, cnt = 0;
2997 if (!tree || !caseVals)
3000 /* the criteria for creating a jump table is */
3001 /* all integer numbers between the maximum & minimum must */
3002 /* be present , the maximum value should not exceed 255 */
3003 min = max = (int) floatFromVal (vch = caseVals);
3004 sprintf (buffer, "_case_%d_%d",
3005 tree->values.switchVals.swNum,
3007 addSet (&labels, newiTempLabel (buffer));
3009 /* if there is only one case value then no need */
3010 if (!(vch = vch->next))
3015 if (((t = (int) floatFromVal (vch)) - max) != 1)
3017 sprintf (buffer, "_case_%d_%d",
3018 tree->values.switchVals.swNum,
3020 addSet (&labels, newiTempLabel (buffer));
3026 /* if the number of case statements <= 2 then */
3027 /* it is not economical to create the jump table */
3028 /* since two compares are needed for boundary conditions */
3029 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3032 if (tree->values.switchVals.swDefault)
3033 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3035 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3037 falseLabel = newiTempLabel (buffer);
3039 /* so we can create a jumptable */
3040 /* first we rule out the boundary conditions */
3041 /* if only optimization says so */
3042 if (!optimize.noJTabBoundary)
3044 sym_link *cetype = getSpec (operandType (cond));
3045 /* no need to check the lower bound if
3046 the condition is unsigned & minimum value is zero */
3047 if (!(min == 0 && SPEC_USIGN (cetype)))
3049 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3050 ic = newiCodeCondition (boundary, falseLabel, NULL);
3054 /* now for upper bounds */
3055 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3056 ic = newiCodeCondition (boundary, falseLabel, NULL);
3060 /* if the min is not zero then we no make it zero */
3063 cond = geniCodeSubtract (cond, operandFromLit (min));
3064 setOperandType (cond, UCHARTYPE);
3067 /* now create the jumptable */
3068 ic = newiCode (JUMPTABLE, NULL, NULL);
3069 IC_JTCOND (ic) = cond;
3070 IC_JTLABELS (ic) = labels;
3075 /*-----------------------------------------------------------------*/
3076 /* geniCodeSwitch - changes a switch to a if statement */
3077 /*-----------------------------------------------------------------*/
3079 geniCodeSwitch (ast * tree,int lvl)
3082 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3083 value *caseVals = tree->values.switchVals.swVals;
3084 symbol *trueLabel, *falseLabel;
3086 /* if we can make this a jump table */
3087 if (geniCodeJumpTable (cond, caseVals, tree))
3088 goto jumpTable; /* no need for the comparison */
3090 /* for the cases defined do */
3094 operand *compare = geniCodeLogic (cond,
3095 operandFromValue (caseVals),
3098 sprintf (buffer, "_case_%d_%d",
3099 tree->values.switchVals.swNum,
3100 (int) floatFromVal (caseVals));
3101 trueLabel = newiTempLabel (buffer);
3103 ic = newiCodeCondition (compare, trueLabel, NULL);
3105 caseVals = caseVals->next;
3110 /* if default is present then goto break else break */
3111 if (tree->values.switchVals.swDefault)
3112 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3114 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3116 falseLabel = newiTempLabel (buffer);
3117 geniCodeGoto (falseLabel);
3120 ast2iCode (tree->right,lvl+1);
3123 /*-----------------------------------------------------------------*/
3124 /* geniCodeInline - intermediate code for inline assembler */
3125 /*-----------------------------------------------------------------*/
3127 geniCodeInline (ast * tree)
3131 ic = newiCode (INLINEASM, NULL, NULL);
3132 IC_INLINE (ic) = tree->values.inlineasm;
3136 /*-----------------------------------------------------------------*/
3137 /* geniCodeArrayInit - intermediate code for array initializer */
3138 /*-----------------------------------------------------------------*/
3140 geniCodeArrayInit (ast * tree, operand *array)
3144 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3145 ic = newiCode (ARRAYINIT, array, NULL);
3146 IC_ARRAYILIST (ic) = tree->values.constlist;
3148 operand *left=newOperand(), *right=newOperand();
3149 left->type=right->type=SYMBOL;
3150 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3151 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3152 ic = newiCode (ARRAYINIT, left, right);
3157 /*-----------------------------------------------------------------*/
3158 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3159 /* particular case. Ie : assigning or dereferencing array or ptr */
3160 /*-----------------------------------------------------------------*/
3161 set * lvaluereqSet = NULL;
3162 typedef struct lvalItem
3169 /*-----------------------------------------------------------------*/
3170 /* addLvaluereq - add a flag for lvalreq for current ast level */
3171 /*-----------------------------------------------------------------*/
3172 void addLvaluereq(int lvl)
3174 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3177 addSetHead(&lvaluereqSet,lpItem);
3180 /*-----------------------------------------------------------------*/
3181 /* delLvaluereq - del a flag for lvalreq for current ast level */
3182 /*-----------------------------------------------------------------*/
3186 lpItem = getSet(&lvaluereqSet);
3187 if(lpItem) Safe_free(lpItem);
3189 /*-----------------------------------------------------------------*/
3190 /* clearLvaluereq - clear lvalreq flag */
3191 /*-----------------------------------------------------------------*/
3192 void clearLvaluereq()
3195 lpItem = peekSet(lvaluereqSet);
3196 if(lpItem) lpItem->req = 0;
3198 /*-----------------------------------------------------------------*/
3199 /* getLvaluereq - get the last lvalreq level */
3200 /*-----------------------------------------------------------------*/
3201 int getLvaluereqLvl()
3204 lpItem = peekSet(lvaluereqSet);
3205 if(lpItem) return lpItem->lvl;
3208 /*-----------------------------------------------------------------*/
3209 /* isLvaluereq - is lvalreq valid for this level ? */
3210 /*-----------------------------------------------------------------*/
3211 int isLvaluereq(int lvl)
3214 lpItem = peekSet(lvaluereqSet);
3215 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3219 /*-----------------------------------------------------------------*/
3220 /* ast2iCode - creates an icodeList from an ast */
3221 /*-----------------------------------------------------------------*/
3223 ast2iCode (ast * tree,int lvl)
3225 operand *left = NULL;
3226 operand *right = NULL;
3229 /* set the global variables for filename & line number */
3231 filename = tree->filename;
3233 lineno = tree->lineno;
3235 block = tree->block;
3237 scopeLevel = tree->level;
3239 if (tree->type == EX_VALUE)
3240 return operandFromValue (tree->opval.val);
3242 if (tree->type == EX_LINK)
3243 return operandFromLink (tree->opval.lnk);
3245 /* if we find a nullop */
3246 if (tree->type == EX_OP &&
3247 (tree->opval.op == NULLOP ||
3248 tree->opval.op == BLOCK))
3250 ast2iCode (tree->left,lvl+1);
3251 ast2iCode (tree->right,lvl+1);
3255 /* special cases for not evaluating */
3256 if (tree->opval.op != ':' &&
3257 tree->opval.op != '?' &&
3258 tree->opval.op != CALL &&
3259 tree->opval.op != IFX &&
3260 tree->opval.op != LABEL &&
3261 tree->opval.op != GOTO &&
3262 tree->opval.op != SWITCH &&
3263 tree->opval.op != FUNCTION &&
3264 tree->opval.op != INLINEASM)
3267 if (IS_ASSIGN_OP (tree->opval.op) ||
3268 IS_DEREF_OP (tree) ||
3269 (tree->opval.op == '&' && !tree->right) ||
3270 tree->opval.op == PTR_OP)
3273 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3274 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3277 left = operandFromAst (tree->left,lvl);
3279 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3280 left = geniCodeRValue (left, TRUE);
3284 left = operandFromAst (tree->left,lvl);
3286 if (tree->opval.op == INC_OP ||
3287 tree->opval.op == DEC_OP)
3290 right = operandFromAst (tree->right,lvl);
3295 right = operandFromAst (tree->right,lvl);
3299 /* now depending on the type of operand */
3300 /* this will be a biggy */
3301 switch (tree->opval.op)
3304 case '[': /* array operation */
3306 //sym_link *ltype = operandType (left);
3307 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3308 left = geniCodeRValue (left, FALSE);
3309 right = geniCodeRValue (right, TRUE);
3312 return geniCodeArray (left, right,lvl);
3314 case '.': /* structure dereference */
3315 if (IS_PTR (operandType (left)))
3316 left = geniCodeRValue (left, TRUE);
3318 left = geniCodeRValue (left, FALSE);
3320 return geniCodeStruct (left, right, tree->lvalue);
3322 case PTR_OP: /* structure pointer dereference */
3325 pType = operandType (left);
3326 left = geniCodeRValue (left, TRUE);
3328 setOClass (pType, getSpec (operandType (left)));
3331 return geniCodeStruct (left, right, tree->lvalue);
3333 case INC_OP: /* increment operator */
3335 return geniCodePostInc (left);
3337 return geniCodePreInc (right);
3339 case DEC_OP: /* decrement operator */
3341 return geniCodePostDec (left);
3343 return geniCodePreDec (right);
3345 case '&': /* bitwise and or address of operator */
3347 { /* this is a bitwise operator */
3348 left = geniCodeRValue (left, FALSE);
3349 right = geniCodeRValue (right, FALSE);
3350 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3353 return geniCodeAddressOf (left);
3355 case '|': /* bitwise or & xor */
3357 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3358 geniCodeRValue (right, FALSE),
3363 return geniCodeDivision (geniCodeRValue (left, FALSE),
3364 geniCodeRValue (right, FALSE));
3367 return geniCodeModulus (geniCodeRValue (left, FALSE),
3368 geniCodeRValue (right, FALSE));
3371 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3372 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3374 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3378 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3379 geniCodeRValue (right, FALSE));
3381 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3385 return geniCodeAdd (geniCodeRValue (left, FALSE),
3386 geniCodeRValue (right, FALSE),lvl);
3388 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3391 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3392 geniCodeRValue (right, FALSE));
3395 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3396 geniCodeRValue (right, FALSE));
3398 return geniCodeCast (operandType (left),
3399 geniCodeRValue (right, FALSE), FALSE);
3405 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3409 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3410 setOperandType (op, UCHARTYPE);
3421 return geniCodeLogic (geniCodeRValue (left, FALSE),
3422 geniCodeRValue (right, FALSE),
3425 return geniCodeConditional (tree,lvl);
3428 return operandFromLit (getSize (tree->right->ftype));
3432 sym_link *rtype = operandType (right);
3433 sym_link *ltype = operandType (left);
3434 if (IS_PTR (rtype) && IS_ITEMP (right)
3435 && right->isaddr && compareType (rtype->next, ltype) == 1)
3436 right = geniCodeRValue (right, TRUE);
3438 right = geniCodeRValue (right, FALSE);
3440 geniCodeAssign (left, right, 0);
3445 geniCodeAssign (left,
3446 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3448 geniCodeRValue (right, FALSE),FALSE), 0);
3452 geniCodeAssign (left,
3453 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3455 geniCodeRValue (right, FALSE)), 0);
3458 geniCodeAssign (left,
3459 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3461 geniCodeRValue (right, FALSE)), 0);
3464 sym_link *rtype = operandType (right);
3465 sym_link *ltype = operandType (left);
3466 if (IS_PTR (rtype) && IS_ITEMP (right)
3467 && right->isaddr && compareType (rtype->next, ltype) == 1)
3468 right = geniCodeRValue (right, TRUE);
3470 right = geniCodeRValue (right, FALSE);
3473 return geniCodeAssign (left,
3474 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3480 sym_link *rtype = operandType (right);
3481 sym_link *ltype = operandType (left);
3482 if (IS_PTR (rtype) && IS_ITEMP (right)
3483 && right->isaddr && compareType (rtype->next, ltype) == 1)
3485 right = geniCodeRValue (right, TRUE);
3489 right = geniCodeRValue (right, FALSE);
3492 geniCodeAssign (left,
3493 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3499 geniCodeAssign (left,
3500 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3502 geniCodeRValue (right, FALSE)), 0);
3505 geniCodeAssign (left,
3506 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3508 geniCodeRValue (right, FALSE)), 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);
3527 geniCodeAssign (left,
3528 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3530 geniCodeRValue (right, FALSE),
3532 operandType (left)), 0);
3534 return geniCodeRValue (right, FALSE);
3537 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3540 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3541 return ast2iCode (tree->right,lvl+1);
3544 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3545 return ast2iCode (tree->right,lvl+1);
3548 geniCodeFunctionBody (tree,lvl);
3552 geniCodeReturn (right);
3556 geniCodeIfx (tree,lvl);
3560 geniCodeSwitch (tree,lvl);
3564 geniCodeInline (tree);
3568 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3575 /*-----------------------------------------------------------------*/
3576 /* reverseICChain - gets from the list and creates a linkedlist */
3577 /*-----------------------------------------------------------------*/
3584 while ((loop = getSet (&iCodeChain)))
3596 /*-----------------------------------------------------------------*/
3597 /* iCodeFromAst - given an ast will convert it to iCode */
3598 /*-----------------------------------------------------------------*/
3600 iCodeFromAst (ast * tree)
3602 returnLabel = newiTempLabel ("_return");
3603 entryLabel = newiTempLabel ("_entry");
3605 return reverseiCChain ();