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 if (SPEC_USIGN(val->type)) {
140 v=SPEC_CVAL(val->type).v_ulong;
142 v=SPEC_CVAL(val->type).v_long;
145 if (SPEC_USIGN(val->type)) {
146 v=SPEC_CVAL(val->type).v_uint;
148 v=SPEC_CVAL(val->type).v_int;
154 // this could be a good idea
155 if (options.pedantic)
159 if (SPEC_NOUN(ltype)==FLOAT) {
164 if (!SPEC_USIGN(val->type) && v<0) {
166 if (SPEC_USIGN(ltype) && (pedantic>1)) {
172 // if very pedantic: "char c=200" is not allowed
173 if (pedantic>1 && !SPEC_USIGN(ltype)) {
174 max = max/2 + negative;
182 sprintf (message, "for %s %s in %s",
183 SPEC_USIGN(ltype) ? "unsigned" : "signed",
184 nounName(ltype), msg);
185 werror (W_CONST_RANGE, message);
192 /*-----------------------------------------------------------------*/
193 /* operandName - returns the name of the operand */
194 /*-----------------------------------------------------------------*/
196 printOperand (operand * op, FILE * file)
213 opetype = getSpec (operandType (op));
214 if (SPEC_NOUN (opetype) == V_FLOAT)
215 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
217 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
218 printTypeChain (operandType (op), file);
225 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
226 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
228 OP_LIVEFROM (op), OP_LIVETO (op),
229 OP_SYMBOL (op)->stack,
230 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
231 OP_SYMBOL(op)->ruonly
235 printTypeChain (operandType (op), file);
236 if (SPIL_LOC (op) && IS_ITEMP (op))
237 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
242 /* if assigned to registers */
243 if (OP_SYMBOL (op)->nRegs)
245 if (OP_SYMBOL (op)->isspilt)
247 if (!OP_SYMBOL (op)->remat)
248 if (OP_SYMBOL (op)->usl.spillLoc)
249 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
250 OP_SYMBOL (op)->usl.spillLoc->rname :
251 OP_SYMBOL (op)->usl.spillLoc->name));
253 fprintf (file, "[err]");
255 fprintf (file, "[remat]");
261 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
262 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
267 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
268 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
269 /* if assigned to registers */
270 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
276 OP_SYMBOL (op)->regs[i]->name :
285 printTypeChain (op->operand.typeOperand, file);
291 fprintf (file, "\n");
296 /*-----------------------------------------------------------------*/
297 /* print functions */
298 /*-----------------------------------------------------------------*/
299 PRINTFUNC (picGetValueAtAddr)
302 printOperand (IC_RESULT (ic), of);
305 printOperand (IC_LEFT (ic), of);
311 PRINTFUNC (picSetValueAtAddr)
315 printOperand (IC_LEFT (ic), of);
316 fprintf (of, "] = ");
317 printOperand (IC_RIGHT (ic), of);
321 PRINTFUNC (picAddrOf)
324 printOperand (IC_RESULT (ic), of);
325 if (IS_ITEMP (IC_LEFT (ic)))
328 fprintf (of, " = &[");
329 printOperand (IC_LEFT (ic), of);
332 if (IS_ITEMP (IC_LEFT (ic)))
333 fprintf (of, " offsetAdd ");
336 printOperand (IC_RIGHT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
344 PRINTFUNC (picJumpTable)
349 fprintf (of, "%s\t", s);
350 printOperand (IC_JTCOND (ic), of);
352 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
353 sym = setNextItem (IC_JTLABELS (ic)))
354 fprintf (of, "\t\t\t%s\n", sym->name);
357 PRINTFUNC (picGeneric)
360 printOperand (IC_RESULT (ic), of);
362 printOperand (IC_LEFT (ic), of);
363 fprintf (of, " %s ", s);
364 printOperand (IC_RIGHT (ic), of);
368 PRINTFUNC (picGenericOne)
373 printOperand (IC_RESULT (ic), of);
379 fprintf (of, "%s ", s);
380 printOperand (IC_LEFT (ic), of);
383 if (!IC_RESULT (ic) && !IC_LEFT (ic))
392 printOperand (IC_RESULT (ic), of);
394 printOperand (IC_LEFT (ic), of);
395 printOperand (IC_RIGHT (ic), of);
400 PRINTFUNC (picAssign)
404 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
407 printOperand (IC_RESULT (ic), of);
409 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
412 fprintf (of, " %s ", s);
413 printOperand (IC_RIGHT (ic), of);
420 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
426 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
433 printOperand (IC_COND (ic), of);
436 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
439 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
441 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
445 PRINTFUNC (picInline)
447 fprintf (of, "%s", IC_INLINE (ic));
450 PRINTFUNC (picReceive)
452 printOperand (IC_RESULT (ic), of);
453 fprintf (of, " = %s ", s);
454 printOperand (IC_LEFT (ic), of);
458 /*-----------------------------------------------------------------*/
459 /* piCode - prints one iCode */
460 /*-----------------------------------------------------------------*/
462 piCode (void *item, FILE * of)
470 icTab = getTableEntry (ic->op);
471 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
472 ic->filename, ic->lineno,
473 ic->seq, ic->key, ic->depth, ic->supportRtn);
474 icTab->iCodePrint (of, ic, icTab->printName);
480 printiCChain(ic,stdout);
482 /*-----------------------------------------------------------------*/
483 /* printiCChain - prints intermediate code for humans */
484 /*-----------------------------------------------------------------*/
486 printiCChain (iCode * icChain, FILE * of)
493 for (loop = icChain; loop; loop = loop->next)
495 if ((icTab = getTableEntry (loop->op)))
497 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
498 loop->filename, loop->lineno,
499 loop->seq, loop->key, loop->depth, loop->supportRtn);
501 icTab->iCodePrint (of, loop, icTab->printName);
507 /*-----------------------------------------------------------------*/
508 /* newOperand - allocate, init & return a new iCode */
509 /*-----------------------------------------------------------------*/
515 op = Safe_alloc ( sizeof (operand));
521 /*-----------------------------------------------------------------*/
522 /* newiCode - create and return a new iCode entry initialised */
523 /*-----------------------------------------------------------------*/
525 newiCode (int op, operand * left, operand * right)
529 ic = Safe_alloc ( sizeof (iCode));
532 ic->filename = filename;
534 ic->level = scopeLevel;
536 ic->key = iCodeKey++;
538 IC_RIGHT (ic) = right;
543 /*-----------------------------------------------------------------*/
544 /* newiCode for conditional statements */
545 /*-----------------------------------------------------------------*/
547 newiCodeCondition (operand * condition,
553 if (IS_VOID(operandType(condition))) {
554 werror(E_VOID_VALUE_USED);
557 ic = newiCode (IFX, NULL, NULL);
558 IC_COND (ic) = condition;
559 IC_TRUE (ic) = trueLabel;
560 IC_FALSE (ic) = falseLabel;
564 /*-----------------------------------------------------------------*/
565 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
566 /*-----------------------------------------------------------------*/
568 newiCodeLabelGoto (int op, symbol * label)
572 ic = newiCode (op, NULL, NULL);
574 ic->argLabel.label = label;
576 IC_RIGHT (ic) = NULL;
577 IC_RESULT (ic) = NULL;
581 /*-----------------------------------------------------------------*/
582 /* newiTemp - allocate & return a newItemp Variable */
583 /*-----------------------------------------------------------------*/
590 sprintf (buffer, "%s", s);
592 sprintf (buffer, "iTemp%d", iTempNum++);
593 itmp = newSymbol (buffer, 1);
594 strcpy (itmp->rname, itmp->name);
600 /*-----------------------------------------------------------------*/
601 /* newiTempLabel - creates a temp variable label */
602 /*-----------------------------------------------------------------*/
604 newiTempLabel (char *s)
608 /* check if this alredy exists */
609 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
613 itmplbl = newSymbol (s, 1);
616 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
617 itmplbl = newSymbol (buffer, 1);
622 itmplbl->key = labelKey++;
623 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
627 /*-----------------------------------------------------------------*/
628 /* newiTempPreheaderLabel - creates a new preheader label */
629 /*-----------------------------------------------------------------*/
631 newiTempPreheaderLabel ()
635 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
636 itmplbl = newSymbol (buffer, 1);
640 itmplbl->key = labelKey++;
641 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
646 /*-----------------------------------------------------------------*/
647 /* initiCode - initialises some iCode related stuff */
648 /*-----------------------------------------------------------------*/
655 /*-----------------------------------------------------------------*/
656 /* copyiCode - make a copy of the iCode given */
657 /*-----------------------------------------------------------------*/
659 copyiCode (iCode * ic)
661 iCode *nic = newiCode (ic->op, NULL, NULL);
663 nic->lineno = ic->lineno;
664 nic->filename = ic->filename;
665 nic->block = ic->block;
666 nic->level = ic->level;
667 nic->parmBytes = ic->parmBytes;
669 /* deal with the special cases first */
673 IC_COND (nic) = operandFromOperand (IC_COND (ic));
674 IC_TRUE (nic) = IC_TRUE (ic);
675 IC_FALSE (nic) = IC_FALSE (ic);
679 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
680 IC_JTLABELS (nic) = IC_JTLABELS (ic);
685 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
686 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
690 IC_INLINE (nic) = IC_INLINE (ic);
694 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
698 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
699 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
700 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
706 /*-----------------------------------------------------------------*/
707 /* getTableEntry - gets the table entry for the given operator */
708 /*-----------------------------------------------------------------*/
710 getTableEntry (int oper)
714 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
715 if (oper == codeTable[i].icode)
716 return &codeTable[i];
721 /*-----------------------------------------------------------------*/
722 /* newiTempOperand - new intermediate temp operand */
723 /*-----------------------------------------------------------------*/
725 newiTempOperand (sym_link * type, char throwType)
728 operand *op = newOperand ();
732 itmp = newiTemp (NULL);
734 etype = getSpec (type);
736 if (IS_LITERAL (etype))
739 /* copy the type information */
741 itmp->etype = getSpec (itmp->type = (throwType ? type :
742 copyLinkChain (type)));
743 if (IS_LITERAL (itmp->etype))
745 SPEC_SCLS (itmp->etype) = S_REGISTER;
746 SPEC_OCLS (itmp->etype) = reg;
749 op->operand.symOperand = itmp;
750 op->key = itmp->key = ++operandKey;
754 /*-----------------------------------------------------------------*/
755 /* operandType - returns the type chain for an operand */
756 /*-----------------------------------------------------------------*/
758 operandType (operand * op)
760 /* depending on type of operand */
765 return op->operand.valOperand->type;
768 return op->operand.symOperand->type;
771 return op->operand.typeOperand;
773 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
774 " operand type not known ");
775 assert (0); /* should never come here */
776 /* Just to keep the compiler happy */
777 return (sym_link *) 0;
781 /*-----------------------------------------------------------------*/
782 /* isParamterToCall - will return 1 if op is a parameter to args */
783 /*-----------------------------------------------------------------*/
785 isParameterToCall (value * args, operand * op)
792 isSymbolEqual (op->operand.symOperand, tval->sym))
799 /*-----------------------------------------------------------------*/
800 /* isOperandGlobal - return 1 if operand is a global variable */
801 /*-----------------------------------------------------------------*/
803 isOperandGlobal (operand * op)
811 if (op->type == SYMBOL &&
812 (op->operand.symOperand->level == 0 ||
813 IS_STATIC (op->operand.symOperand->etype) ||
814 IS_EXTERN (op->operand.symOperand->etype))
821 /*-----------------------------------------------------------------*/
822 /* isOperandVolatile - return 1 if the operand is volatile */
823 /*-----------------------------------------------------------------*/
825 isOperandVolatile (operand * op, bool chkTemp)
830 if (IS_ITEMP (op) && !chkTemp)
833 opetype = getSpec (optype = operandType (op));
835 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
838 if (IS_VOLATILE (opetype))
843 /*-----------------------------------------------------------------*/
844 /* isOperandLiteral - returns 1 if an operand contains a literal */
845 /*-----------------------------------------------------------------*/
847 isOperandLiteral (operand * op)
854 opetype = getSpec (operandType (op));
856 if (IS_LITERAL (opetype))
862 /*-----------------------------------------------------------------*/
863 /* isOperandInFarSpace - will return true if operand is in farSpace */
864 /*-----------------------------------------------------------------*/
866 isOperandInFarSpace (operand * op)
876 if (!IS_TRUE_SYMOP (op))
879 etype = SPIL_LOC (op)->etype;
885 etype = getSpec (operandType (op));
887 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
890 /*------------------------------------------------------------------*/
891 /* isOperandInDirSpace - will return true if operand is in dirSpace */
892 /*------------------------------------------------------------------*/
894 isOperandInDirSpace (operand * op)
904 if (!IS_TRUE_SYMOP (op))
907 etype = SPIL_LOC (op)->etype;
913 etype = getSpec (operandType (op));
915 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
918 /*-----------------------------------------------------------------*/
919 /* isOperandOnStack - will return true if operand is on stack */
920 /*-----------------------------------------------------------------*/
922 isOperandOnStack (operand * op)
932 etype = getSpec (operandType (op));
934 return ((IN_STACK (etype)) ? TRUE : FALSE);
937 /*-----------------------------------------------------------------*/
938 /* operandLitValue - literal value of an operand */
939 /*-----------------------------------------------------------------*/
941 operandLitValue (operand * op)
943 assert (isOperandLiteral (op));
945 return floatFromVal (op->operand.valOperand);
948 /*-----------------------------------------------------------------*/
949 /* getBuiltInParms - returns parameters to a builtin functions */
950 /*-----------------------------------------------------------------*/
951 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
956 /* builtin functions uses only SEND for parameters */
957 while (ic->op != CALL) {
958 assert(ic->op == SEND && ic->builtinSEND);
959 ic->generated = 1; /* mark the icode as generated */
960 parms[*pcount] = IC_LEFT(ic);
966 /* make sure this is a builtin function call */
967 assert(IS_SYMOP(IC_LEFT(ic)));
968 ftype = operandType(IC_LEFT(ic));
969 assert(IFFUNC_ISBUILTIN(ftype));
973 /*-----------------------------------------------------------------*/
974 /* operandOperation - perforoms operations on operands */
975 /*-----------------------------------------------------------------*/
977 operandOperation (operand * left, operand * right,
978 int op, sym_link * type)
980 sym_link *let , *ret=NULL;
981 operand *retval = (operand *) 0;
983 assert (isOperandLiteral (left));
984 let = getSpec(operandType(left));
986 assert (isOperandLiteral (right));
987 ret = getSpec(operandType(left));
993 retval = operandFromValue (valCastLiteral (type,
994 operandLitValue (left) +
995 operandLitValue (right)));
998 retval = operandFromValue (valCastLiteral (type,
999 operandLitValue (left) -
1000 operandLitValue (right)));
1003 retval = operandFromValue (valCastLiteral (type,
1004 operandLitValue (left) *
1005 operandLitValue (right)));
1008 if ((unsigned long) operandLitValue (right) == 0)
1010 werror (E_DIVIDE_BY_ZERO);
1015 retval = operandFromValue (valCastLiteral (type,
1016 operandLitValue (left) /
1017 operandLitValue (right)));
1020 if ((unsigned long) operandLitValue (right) == 0) {
1021 werror (E_DIVIDE_BY_ZERO);
1025 retval = operandFromLit ((SPEC_USIGN(let) ?
1026 (unsigned long) operandLitValue (left) :
1027 (long) operandLitValue (left)) %
1029 (unsigned long) operandLitValue (right) :
1030 (long) operandLitValue (right)));
1034 retval = operandFromLit ((SPEC_USIGN(let) ?
1035 (unsigned long) operandLitValue (left) :
1036 (long) operandLitValue (left)) <<
1038 (unsigned long) operandLitValue (right) :
1039 (long) operandLitValue (right)));
1042 retval = operandFromLit ((SPEC_USIGN(let) ?
1043 (unsigned long) operandLitValue (left) :
1044 (long) operandLitValue (left)) >>
1046 (unsigned long) operandLitValue (right) :
1047 (long) operandLitValue (right)));
1050 retval = operandFromLit (operandLitValue (left) ==
1051 operandLitValue (right));
1054 retval = operandFromLit (operandLitValue (left) <
1055 operandLitValue (right));
1058 retval = operandFromLit (operandLitValue (left) <=
1059 operandLitValue (right));
1062 retval = operandFromLit (operandLitValue (left) !=
1063 operandLitValue (right));
1066 retval = operandFromLit (operandLitValue (left) >
1067 operandLitValue (right));
1070 retval = operandFromLit (operandLitValue (left) >=
1071 operandLitValue (right));
1074 retval = operandFromLit ((long)operandLitValue(left) &
1075 (long)operandLitValue(right));
1078 retval = operandFromLit ((long)operandLitValue (left) |
1079 (long)operandLitValue (right));
1082 retval = operandFromLit ((long)operandLitValue (left) ^
1083 (long)operandLitValue (right));
1086 retval = operandFromLit (operandLitValue (left) &&
1087 operandLitValue (right));
1090 retval = operandFromLit (operandLitValue (left) ||
1091 operandLitValue (right));
1095 long i = (long) operandLitValue (left);
1097 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1103 long i = (long) operandLitValue (left);
1105 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1111 retval = operandFromLit (-1 * operandLitValue (left));
1115 retval = operandFromLit (~((long) operandLitValue (left)));
1119 retval = operandFromLit (!operandLitValue (left));
1123 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1124 " operandOperation invalid operator ");
1132 /*-----------------------------------------------------------------*/
1133 /* isOperandEqual - compares two operand & return 1 if they r = */
1134 /*-----------------------------------------------------------------*/
1136 isOperandEqual (operand * left, operand * right)
1138 /* if the pointers are equal then they are equal */
1142 /* if either of them null then false */
1143 if (!left || !right)
1146 if (left->type != right->type)
1149 if (IS_SYMOP (left) && IS_SYMOP (right))
1150 return left->key == right->key;
1152 /* if types are the same */
1156 return isSymbolEqual (left->operand.symOperand,
1157 right->operand.symOperand);
1159 return (floatFromVal (left->operand.valOperand) ==
1160 floatFromVal (right->operand.valOperand));
1162 if (compareType (left->operand.typeOperand,
1163 right->operand.typeOperand) == 1)
1170 /*-------------------------------------------------------------------*/
1171 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1172 /*-------------------------------------------------------------------*/
1174 isiCodeEqual (iCode * left, iCode * right)
1176 /* if the same pointer */
1180 /* if either of them null */
1181 if (!left || !right)
1184 /* if operand are the same */
1185 if (left->op == right->op)
1188 /* compare all the elements depending on type */
1189 if (left->op != IFX)
1191 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1193 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1199 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1201 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1203 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1212 /*-----------------------------------------------------------------*/
1213 /* newiTempFromOp - create a temp Operand with same attributes */
1214 /*-----------------------------------------------------------------*/
1216 newiTempFromOp (operand * op)
1226 nop = newiTempOperand (operandType (op), TRUE);
1227 nop->isaddr = op->isaddr;
1228 nop->isvolatile = op->isvolatile;
1229 nop->isGlobal = op->isGlobal;
1230 nop->isLiteral = op->isLiteral;
1231 nop->usesDefs = op->usesDefs;
1232 nop->isParm = op->isParm;
1236 /*-----------------------------------------------------------------*/
1237 /* operand from operand - creates an operand holder for the type */
1238 /*-----------------------------------------------------------------*/
1240 operandFromOperand (operand * op)
1246 nop = newOperand ();
1247 nop->type = op->type;
1248 nop->isaddr = op->isaddr;
1250 nop->isvolatile = op->isvolatile;
1251 nop->isGlobal = op->isGlobal;
1252 nop->isLiteral = op->isLiteral;
1253 nop->usesDefs = op->usesDefs;
1254 nop->isParm = op->isParm;
1259 nop->operand.symOperand = op->operand.symOperand;
1262 nop->operand.valOperand = op->operand.valOperand;
1265 nop->operand.typeOperand = op->operand.typeOperand;
1272 /*-----------------------------------------------------------------*/
1273 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1274 /*-----------------------------------------------------------------*/
1276 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1278 operand *nop = operandFromOperand (op);
1280 if (nop->type == SYMBOL)
1282 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1283 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1289 /*-----------------------------------------------------------------*/
1290 /* operandFromSymbol - creates an operand from a symbol */
1291 /*-----------------------------------------------------------------*/
1293 operandFromSymbol (symbol * sym)
1298 /* if the symbol's type is a literal */
1299 /* then it is an enumerator type */
1300 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1301 return operandFromValue (valFromType (sym->etype));
1304 sym->key = ++operandKey;
1306 /* if this an implicit variable, means struct/union */
1307 /* member so just return it */
1308 if (sym->implicit || IS_FUNC (sym->type))
1312 op->operand.symOperand = sym;
1314 op->isvolatile = isOperandVolatile (op, TRUE);
1315 op->isGlobal = isOperandGlobal (op);
1319 /* under the following conditions create a
1320 register equivalent for a local symbol */
1321 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1322 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1323 (!(options.model == MODEL_FLAT24)) ) &&
1324 options.stackAuto == 0)
1327 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1328 !IS_FUNC (sym->type) && /* not a function */
1329 !sym->_isparm && /* not a parameter */
1330 sym->level && /* is a local variable */
1331 !sym->addrtaken && /* whose address has not been taken */
1332 !sym->reqv && /* does not already have a reg equivalence */
1333 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1334 !IS_STATIC (sym->etype) && /* and not declared static */
1335 !sym->islbl && /* not a label */
1336 ok && /* farspace check */
1337 !IS_BITVAR (sym->etype) /* not a bit variable */
1341 /* we will use it after all optimizations
1342 and before liveRange calculation */
1343 sym->reqv = newiTempOperand (sym->type, 0);
1344 sym->reqv->key = sym->key;
1345 OP_SYMBOL (sym->reqv)->key = sym->key;
1346 OP_SYMBOL (sym->reqv)->isreqv = 1;
1347 OP_SYMBOL (sym->reqv)->islocal = 1;
1348 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1349 SPIL_LOC (sym->reqv) = sym;
1352 if (!IS_AGGREGATE (sym->type))
1356 op->operand.symOperand = sym;
1359 op->isvolatile = isOperandVolatile (op, TRUE);
1360 op->isGlobal = isOperandGlobal (op);
1361 op->isPtr = IS_PTR (operandType (op));
1362 op->isParm = sym->_isparm;
1367 /* itemp = &[_symbol] */
1369 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1370 IC_LEFT (ic)->type = SYMBOL;
1371 IC_LEFT (ic)->operand.symOperand = sym;
1372 IC_LEFT (ic)->key = sym->key;
1373 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1374 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1375 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1378 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1379 if (IS_ARRAY (sym->type))
1381 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1382 IC_RESULT (ic)->isaddr = 0;
1385 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1389 return IC_RESULT (ic);
1392 /*-----------------------------------------------------------------*/
1393 /* operandFromValue - creates an operand from value */
1394 /*-----------------------------------------------------------------*/
1396 operandFromValue (value * val)
1400 /* if this is a symbol then do the symbol thing */
1402 return operandFromSymbol (val->sym);
1404 /* this is not a symbol */
1407 op->operand.valOperand = val;
1408 op->isLiteral = isOperandLiteral (op);
1412 /*-----------------------------------------------------------------*/
1413 /* operandFromLink - operand from typeChain */
1414 /*-----------------------------------------------------------------*/
1416 operandFromLink (sym_link * type)
1420 /* operand from sym_link */
1426 op->operand.typeOperand = copyLinkChain (type);
1430 /*-----------------------------------------------------------------*/
1431 /* operandFromLit - makes an operand from a literal value */
1432 /*-----------------------------------------------------------------*/
1434 operandFromLit (double i)
1436 return operandFromValue (valueFromLit (i));
1439 /*-----------------------------------------------------------------*/
1440 /* operandFromAst - creates an operand from an ast */
1441 /*-----------------------------------------------------------------*/
1443 operandFromAst (ast * tree,int lvl)
1449 /* depending on type do */
1453 return ast2iCode (tree,lvl+1);
1457 return operandFromValue (tree->opval.val);
1461 return operandFromLink (tree->opval.lnk);
1465 /* Just to keep the comiler happy */
1466 return (operand *) 0;
1469 /*-----------------------------------------------------------------*/
1470 /* setOperandType - sets the operand's type to the given type */
1471 /*-----------------------------------------------------------------*/
1473 setOperandType (operand * op, sym_link * type)
1475 /* depending on the type of operand */
1480 op->operand.valOperand->etype =
1481 getSpec (op->operand.valOperand->type =
1482 copyLinkChain (type));
1486 if (op->operand.symOperand->isitmp)
1487 op->operand.symOperand->etype =
1488 getSpec (op->operand.symOperand->type =
1489 copyLinkChain (type));
1491 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1492 "attempt to modify type of source");
1496 op->operand.typeOperand = copyLinkChain (type);
1501 /*-----------------------------------------------------------------*/
1502 /* Get size in byte of ptr need to access an array */
1503 /*-----------------------------------------------------------------*/
1505 getArraySizePtr (operand * op)
1507 sym_link *ltype = operandType(op);
1511 int size = getSize(ltype);
1512 return(IS_GENPTR(ltype)?(size-1):size);
1517 sym_link *letype = getSpec(ltype);
1518 switch (PTR_TYPE (SPEC_OCLS (letype)))
1530 return (GPTRSIZE-1);
1539 /*-----------------------------------------------------------------*/
1540 /* perform "usual unary conversions" */
1541 /*-----------------------------------------------------------------*/
1543 usualUnaryConversions (operand * op)
1545 if (IS_INTEGRAL (operandType (op)))
1547 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1550 return geniCodeCast (INTTYPE, op, TRUE);
1556 /*-----------------------------------------------------------------*/
1557 /* perform "usual binary conversions" */
1558 /*-----------------------------------------------------------------*/
1560 usualBinaryConversions (operand ** op1, operand ** op2)
1563 sym_link *rtype = operandType (*op2);
1564 sym_link *ltype = operandType (*op1);
1566 ctype = computeType (ltype, rtype);
1567 *op1 = geniCodeCast (ctype, *op1, TRUE);
1568 *op2 = geniCodeCast (ctype, *op2, TRUE);
1573 /*-----------------------------------------------------------------*/
1574 /* geniCodeValueAtAddress - generate intermeditate code for value */
1576 /*-----------------------------------------------------------------*/
1578 geniCodeRValue (operand * op, bool force)
1581 sym_link *type = operandType (op);
1582 sym_link *etype = getSpec (type);
1584 /* if this is an array & already */
1585 /* an address then return this */
1586 if (IS_AGGREGATE (type) ||
1587 (IS_PTR (type) && !force && !op->isaddr))
1588 return operandFromOperand (op);
1590 /* if this is not an address then must be */
1591 /* rvalue already so return this one */
1595 /* if this is not a temp symbol then */
1596 if (!IS_ITEMP (op) &&
1598 !IN_FARSPACE (SPEC_OCLS (etype)))
1600 op = operandFromOperand (op);
1605 if (IS_SPEC (type) &&
1606 IS_TRUE_SYMOP (op) &&
1607 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1608 /* TARGET_IS_DS390)) */
1609 (options.model == MODEL_FLAT24) ))
1611 op = operandFromOperand (op);
1616 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1617 if (IS_PTR (type) && op->isaddr && force)
1620 type = copyLinkChain (type);
1622 IC_RESULT (ic) = newiTempOperand (type, 1);
1623 IC_RESULT (ic)->isaddr = 0;
1625 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1629 return IC_RESULT (ic);
1632 /*-----------------------------------------------------------------*/
1633 /* geniCodeCast - changes the value from one type to another */
1634 /*-----------------------------------------------------------------*/
1636 geniCodeCast (sym_link * type, operand * op, bool implicit)
1640 sym_link *opetype = getSpec (optype = operandType (op));
1644 /* one of them has size zero then error */
1645 if (IS_VOID (optype))
1647 werror (E_CAST_ZERO);
1651 /* if the operand is already the desired type then do nothing */
1652 if (compareType (type, optype) == 1)
1655 /* if this is a literal then just change the type & return */
1656 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1657 return operandFromValue (valCastLiteral (type,
1658 operandLitValue (op)));
1660 /* if casting to/from pointers, do some checking */
1661 if (IS_PTR(type)) { // to a pointer
1662 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1663 if (IS_INTEGRAL(optype)) {
1664 // maybe this is NULL, than it's ok.
1665 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1666 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1667 // no way to set the storage
1668 if (IS_LITERAL(optype)) {
1669 werror(E_LITERAL_GENERIC);
1672 werror(E_NONPTR2_GENPTR);
1675 } else if (implicit) {
1676 werror(W_INTEGRAL2PTR_NOCAST);
1681 // shouldn't do that with float, array or structure unless to void
1682 if (!IS_VOID(getSpec(type)) &&
1683 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1684 werror(E_INCOMPAT_TYPES);
1688 } else { // from a pointer to a pointer
1689 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1690 // if not a pointer to a function
1691 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1692 if (implicit) { // if not to generic, they have to match
1693 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1694 werror(E_INCOMPAT_PTYPES);
1701 } else { // to a non pointer
1702 if (IS_PTR(optype)) { // from a pointer
1703 if (implicit) { // sneaky
1704 if (IS_INTEGRAL(type)) {
1705 werror(W_PTR2INTEGRAL_NOCAST);
1707 } else { // shouldn't do that with float, array or structure
1708 werror(E_INCOMPAT_TYPES);
1715 printFromToType (optype, type);
1718 /* if they are the same size create an assignment */
1719 if (getSize (type) == getSize (optype) &&
1720 !IS_BITFIELD (type) &&
1722 !IS_FLOAT (optype) &&
1723 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1724 (!IS_SPEC (type) && !IS_SPEC (optype))))
1727 ic = newiCode ('=', NULL, op);
1728 IC_RESULT (ic) = newiTempOperand (type, 0);
1729 SPIL_LOC (IC_RESULT (ic)) =
1730 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1731 IC_RESULT (ic)->isaddr = 0;
1735 ic = newiCode (CAST, operandFromLink (type),
1736 geniCodeRValue (op, FALSE));
1738 IC_RESULT (ic) = newiTempOperand (type, 0);
1741 /* preserve the storage class & output class */
1742 /* of the original variable */
1743 restype = getSpec (operandType (IC_RESULT (ic)));
1744 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1745 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1748 return IC_RESULT (ic);
1751 /*-----------------------------------------------------------------*/
1752 /* geniCodeLabel - will create a Label */
1753 /*-----------------------------------------------------------------*/
1755 geniCodeLabel (symbol * label)
1759 ic = newiCodeLabelGoto (LABEL, label);
1763 /*-----------------------------------------------------------------*/
1764 /* geniCodeGoto - will create a Goto */
1765 /*-----------------------------------------------------------------*/
1767 geniCodeGoto (symbol * label)
1771 ic = newiCodeLabelGoto (GOTO, label);
1775 /*-----------------------------------------------------------------*/
1776 /* geniCodeMultiply - gen intermediate code for multiplication */
1777 /*-----------------------------------------------------------------*/
1779 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1786 /* if they are both literal then we know the result */
1787 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1788 return operandFromValue (valMult (left->operand.valOperand,
1789 right->operand.valOperand));
1791 if (IS_LITERAL(retype)) {
1792 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1795 resType = usualBinaryConversions (&left, &right);
1797 rtype = operandType (right);
1798 retype = getSpec (rtype);
1799 ltype = operandType (left);
1800 letype = getSpec (ltype);
1804 SPEC_NOUN(getSpec(resType))=V_INT;
1807 /* if the right is a literal & power of 2 */
1808 /* then make it a left shift */
1809 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1810 efficient in most cases than 2 bytes result = 2 bytes << literal
1811 if port has 1 byte muldiv */
1812 if (p2 && !IS_FLOAT (letype) &&
1813 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1814 (port->support.muldiv == 1)))
1816 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1818 /* LEFT_OP need same size for left and result, */
1819 left = geniCodeCast (resType, left, TRUE);
1820 ltype = operandType (left);
1822 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1826 ic = newiCode ('*', left, right); /* normal multiplication */
1827 /* if the size left or right > 1 then support routine */
1828 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1832 IC_RESULT (ic) = newiTempOperand (resType, 1);
1835 return IC_RESULT (ic);
1838 /*-----------------------------------------------------------------*/
1839 /* geniCodeDivision - gen intermediate code for division */
1840 /*-----------------------------------------------------------------*/
1842 geniCodeDivision (operand * left, operand * right)
1847 sym_link *rtype = operandType (right);
1848 sym_link *retype = getSpec (rtype);
1849 sym_link *ltype = operandType (left);
1850 sym_link *letype = getSpec (ltype);
1852 resType = usualBinaryConversions (&left, &right);
1854 /* if the right is a literal & power of 2 */
1855 /* then make it a right shift */
1856 if (IS_LITERAL (retype) &&
1857 !IS_FLOAT (letype) &&
1858 (p2 = powof2 ((unsigned long)
1859 floatFromVal (right->operand.valOperand)))) {
1860 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1864 ic = newiCode ('/', left, right); /* normal division */
1865 /* if the size left or right > 1 then support routine */
1866 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1869 IC_RESULT (ic) = newiTempOperand (resType, 0);
1872 return IC_RESULT (ic);
1874 /*-----------------------------------------------------------------*/
1875 /* geniCodeModulus - gen intermediate code for modulus */
1876 /*-----------------------------------------------------------------*/
1878 geniCodeModulus (operand * left, operand * right)
1884 /* if they are both literal then we know the result */
1885 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1886 return operandFromValue (valMod (left->operand.valOperand,
1887 right->operand.valOperand));
1889 resType = usualBinaryConversions (&left, &right);
1891 /* now they are the same size */
1892 ic = newiCode ('%', left, right);
1894 /* if the size left or right > 1 then support routine */
1895 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1897 IC_RESULT (ic) = newiTempOperand (resType, 0);
1900 return IC_RESULT (ic);
1903 /*-----------------------------------------------------------------*/
1904 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1905 /*-----------------------------------------------------------------*/
1907 geniCodePtrPtrSubtract (operand * left, operand * right)
1913 /* if they are both literals then */
1914 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1916 result = operandFromValue (valMinus (left->operand.valOperand,
1917 right->operand.valOperand));
1921 ic = newiCode ('-', left, right);
1923 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1927 return geniCodeDivision (result,
1928 operandFromLit (getSize (ltype->next)));
1931 /*-----------------------------------------------------------------*/
1932 /* geniCodeSubtract - generates code for subtraction */
1933 /*-----------------------------------------------------------------*/
1935 geniCodeSubtract (operand * left, operand * right)
1942 /* if they both pointers then */
1943 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1944 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1945 return geniCodePtrPtrSubtract (left, right);
1947 /* if they are both literal then we know the result */
1948 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1949 && left->isLiteral && right->isLiteral)
1950 return operandFromValue (valMinus (left->operand.valOperand,
1951 right->operand.valOperand));
1953 /* if left is an array or pointer */
1954 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1956 isarray = left->isaddr;
1957 right = geniCodeMultiply (right,
1958 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1959 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1962 { /* make them the same size */
1963 resType = usualBinaryConversions (&left, &right);
1966 ic = newiCode ('-', left, right);
1968 IC_RESULT (ic) = newiTempOperand (resType, 1);
1969 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1971 /* if left or right is a float */
1972 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1976 return IC_RESULT (ic);
1979 /*-----------------------------------------------------------------*/
1980 /* geniCodeAdd - generates iCode for addition */
1981 /*-----------------------------------------------------------------*/
1983 geniCodeAdd (operand * left, operand * right,int lvl)
1991 /* if left is an array then array access */
1992 if (IS_ARRAY (ltype))
1993 return geniCodeArray (left, right,lvl);
1995 /* if the right side is LITERAL zero */
1996 /* return the left side */
1997 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2000 /* if left is literal zero return right */
2001 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2004 /* if left is an array or pointer then size */
2007 isarray = left->isaddr;
2008 // there is no need to multiply with 1
2009 if (getSize(ltype->next)!=1) {
2010 size = operandFromLit (getSize (ltype->next));
2011 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2013 resType = copyLinkChain (ltype);
2016 { /* make them the same size */
2017 resType = usualBinaryConversions (&left, &right);
2020 /* if they are both literals then we know */
2021 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2022 && left->isLiteral && right->isLiteral)
2023 return operandFromValue (valPlus (valFromType (letype),
2024 valFromType (retype)));
2026 ic = newiCode ('+', left, right);
2028 IC_RESULT (ic) = newiTempOperand (resType, 1);
2029 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2031 /* if left or right is a float then support
2033 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2038 return IC_RESULT (ic);
2042 /*-----------------------------------------------------------------*/
2043 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2044 /*-----------------------------------------------------------------*/
2046 aggrToPtr (sym_link * type, bool force)
2052 if (IS_PTR (type) && !force)
2055 etype = getSpec (type);
2059 /* if the output class is generic */
2060 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2061 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2063 /* if the variable was declared a constant */
2064 /* then the pointer points to a constant */
2065 if (IS_CONSTANT (etype))
2066 DCL_PTR_CONST (ptype) = 1;
2068 /* the variable was volatile then pointer to volatile */
2069 if (IS_VOLATILE (etype))
2070 DCL_PTR_VOLATILE (ptype) = 1;
2074 /*-----------------------------------------------------------------*/
2075 /* geniCodeArray2Ptr - array to pointer */
2076 /*-----------------------------------------------------------------*/
2078 geniCodeArray2Ptr (operand * op)
2080 sym_link *optype = operandType (op);
2081 sym_link *opetype = getSpec (optype);
2083 /* set the pointer depending on the storage class */
2084 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2085 DCL_PTR_CONST (optype) = port->mem.code_ro;
2088 /* if the variable was declared a constant */
2089 /* then the pointer points to a constant */
2090 if (IS_CONSTANT (opetype))
2091 DCL_PTR_CONST (optype) = 1;
2093 /* the variable was volatile then pointer to volatile */
2094 if (IS_VOLATILE (opetype))
2095 DCL_PTR_VOLATILE (optype) = 1;
2101 /*-----------------------------------------------------------------*/
2102 /* geniCodeArray - array access */
2103 /*-----------------------------------------------------------------*/
2105 geniCodeArray (operand * left, operand * right,int lvl)
2108 sym_link *ltype = operandType (left);
2112 if (IS_PTR (ltype->next) && left->isaddr)
2114 left = geniCodeRValue (left, FALSE);
2116 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2119 right = geniCodeMultiply (right,
2120 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2122 /* we can check for limits here */
2123 if (isOperandLiteral (right) &&
2126 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2128 werror (E_ARRAY_BOUND);
2129 right = operandFromLit (0);
2132 ic = newiCode ('+', left, right);
2134 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2135 !IS_AGGREGATE (ltype->next) &&
2136 !IS_PTR (ltype->next))
2137 ? ltype : ltype->next), 0);
2139 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2141 return IC_RESULT (ic);
2144 /*-----------------------------------------------------------------*/
2145 /* geniCodeStruct - generates intermediate code for structres */
2146 /*-----------------------------------------------------------------*/
2148 geniCodeStruct (operand * left, operand * right, bool islval)
2151 sym_link *type = operandType (left);
2152 sym_link *etype = getSpec (type);
2154 symbol *element = getStructElement (SPEC_STRUCT (etype),
2155 right->operand.symOperand);
2157 /* add the offset */
2158 ic = newiCode ('+', left, operandFromLit (element->offset));
2160 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2162 /* preserve the storage & output class of the struct */
2163 /* as well as the volatile attribute */
2164 retype = getSpec (operandType (IC_RESULT (ic)));
2165 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2166 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2167 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2169 if (IS_PTR (element->type))
2170 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2172 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2176 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2179 /*-----------------------------------------------------------------*/
2180 /* geniCodePostInc - generate int code for Post increment */
2181 /*-----------------------------------------------------------------*/
2183 geniCodePostInc (operand * op)
2187 sym_link *optype = operandType (op);
2189 operand *rv = (IS_ITEMP (op) ?
2190 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2192 sym_link *rvtype = operandType (rv);
2195 /* if this is not an address we have trouble */
2198 werror (E_LVALUE_REQUIRED, "++");
2202 rOp = newiTempOperand (rvtype, 0);
2203 OP_SYMBOL(rOp)->noSpilLoc = 1;
2206 OP_SYMBOL(rv)->noSpilLoc = 1;
2208 geniCodeAssign (rOp, rv, 0);
2210 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2211 if (IS_FLOAT (rvtype))
2212 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2214 ic = newiCode ('+', rv, operandFromLit (size));
2216 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2219 geniCodeAssign (op, result, 0);
2225 /*-----------------------------------------------------------------*/
2226 /* geniCodePreInc - generate code for preIncrement */
2227 /*-----------------------------------------------------------------*/
2229 geniCodePreInc (operand * op)
2232 sym_link *optype = operandType (op);
2233 operand *rop = (IS_ITEMP (op) ?
2234 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2236 sym_link *roptype = operandType (rop);
2242 werror (E_LVALUE_REQUIRED, "++");
2247 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2248 if (IS_FLOAT (roptype))
2249 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2251 ic = newiCode ('+', rop, operandFromLit (size));
2252 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2256 return geniCodeAssign (op, result, 0);
2259 /*-----------------------------------------------------------------*/
2260 /* geniCodePostDec - generates code for Post decrement */
2261 /*-----------------------------------------------------------------*/
2263 geniCodePostDec (operand * op)
2267 sym_link *optype = operandType (op);
2269 operand *rv = (IS_ITEMP (op) ?
2270 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2272 sym_link *rvtype = operandType (rv);
2275 /* if this is not an address we have trouble */
2278 werror (E_LVALUE_REQUIRED, "--");
2282 rOp = newiTempOperand (rvtype, 0);
2283 OP_SYMBOL(rOp)->noSpilLoc = 1;
2286 OP_SYMBOL(rv)->noSpilLoc = 1;
2288 geniCodeAssign (rOp, rv, 0);
2290 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2291 if (IS_FLOAT (rvtype))
2292 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2294 ic = newiCode ('-', rv, operandFromLit (size));
2296 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2299 geniCodeAssign (op, result, 0);
2305 /*-----------------------------------------------------------------*/
2306 /* geniCodePreDec - generate code for pre decrement */
2307 /*-----------------------------------------------------------------*/
2309 geniCodePreDec (operand * op)
2312 sym_link *optype = operandType (op);
2313 operand *rop = (IS_ITEMP (op) ?
2314 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2316 sym_link *roptype = operandType (rop);
2322 werror (E_LVALUE_REQUIRED, "--");
2327 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2328 if (IS_FLOAT (roptype))
2329 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2331 ic = newiCode ('-', rop, operandFromLit (size));
2332 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2336 return geniCodeAssign (op, result, 0);
2340 /*-----------------------------------------------------------------*/
2341 /* geniCodeBitwise - gen int code for bitWise operators */
2342 /*-----------------------------------------------------------------*/
2344 geniCodeBitwise (operand * left, operand * right,
2345 int oper, sym_link * resType)
2349 left = geniCodeCast (resType, left, TRUE);
2350 right = geniCodeCast (resType, right, TRUE);
2352 ic = newiCode (oper, left, right);
2353 IC_RESULT (ic) = newiTempOperand (resType, 0);
2356 return IC_RESULT (ic);
2359 /*-----------------------------------------------------------------*/
2360 /* geniCodeAddressOf - gens icode for '&' address of operator */
2361 /*-----------------------------------------------------------------*/
2363 geniCodeAddressOf (operand * op)
2367 sym_link *optype = operandType (op);
2368 sym_link *opetype = getSpec (optype);
2370 /* lvalue check already done in decorateType */
2371 /* this must be a lvalue */
2372 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2373 /* werror (E_LVALUE_REQUIRED,"&"); */
2378 p->class = DECLARATOR;
2380 /* set the pointer depending on the storage class */
2381 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2382 DCL_PTR_CONST (p) = port->mem.code_ro;
2384 /* make sure we preserve the const & volatile */
2385 if (IS_CONSTANT (opetype))
2386 DCL_PTR_CONST (p) = 1;
2388 if (IS_VOLATILE (opetype))
2389 DCL_PTR_VOLATILE (p) = 1;
2391 p->next = copyLinkChain (optype);
2393 /* if already a temp */
2396 setOperandType (op, p);
2401 /* other wise make this of the type coming in */
2402 ic = newiCode (ADDRESS_OF, op, NULL);
2403 IC_RESULT (ic) = newiTempOperand (p, 1);
2404 IC_RESULT (ic)->isaddr = 0;
2406 return IC_RESULT (ic);
2408 /*-----------------------------------------------------------------*/
2409 /* setOClass - sets the output class depending on the pointer type */
2410 /*-----------------------------------------------------------------*/
2412 setOClass (sym_link * ptr, sym_link * spec)
2414 switch (DCL_TYPE (ptr))
2417 SPEC_OCLS (spec) = data;
2421 SPEC_OCLS (spec) = generic;
2425 SPEC_OCLS (spec) = xdata;
2429 SPEC_OCLS (spec) = code;
2433 SPEC_OCLS (spec) = idata;
2437 SPEC_OCLS (spec) = xstack;
2441 SPEC_OCLS (spec) = eeprom;
2450 /*-----------------------------------------------------------------*/
2451 /* geniCodeDerefPtr - dereference pointer with '*' */
2452 /*-----------------------------------------------------------------*/
2454 geniCodeDerefPtr (operand * op,int lvl)
2456 sym_link *rtype, *retype;
2457 sym_link *optype = operandType (op);
2459 /* if this is a pointer then generate the rvalue */
2460 if (IS_PTR (optype))
2462 if (IS_TRUE_SYMOP (op))
2465 op = geniCodeRValue (op, TRUE);
2468 op = geniCodeRValue (op, TRUE);
2471 /* now get rid of the pointer part */
2472 if (isLvaluereq(lvl) && IS_ITEMP (op))
2474 retype = getSpec (rtype = copyLinkChain (optype));
2478 retype = getSpec (rtype = copyLinkChain (optype->next));
2481 /* if this is a pointer then outputclass needs 2b updated */
2482 if (IS_PTR (optype))
2483 setOClass (optype, retype);
2485 op->isGptr = IS_GENPTR (optype);
2487 /* if the pointer was declared as a constant */
2488 /* then we cannot allow assignment to the derefed */
2489 if (IS_PTR_CONST (optype))
2490 SPEC_CONST (retype) = 1;
2492 op->isaddr = (IS_PTR (rtype) ||
2493 IS_STRUCT (rtype) ||
2498 if (!isLvaluereq(lvl))
2499 op = geniCodeRValue (op, TRUE);
2501 setOperandType (op, rtype);
2506 /*-----------------------------------------------------------------*/
2507 /* geniCodeUnaryMinus - does a unary minus of the operand */
2508 /*-----------------------------------------------------------------*/
2510 geniCodeUnaryMinus (operand * op)
2513 sym_link *optype = operandType (op);
2515 if (IS_LITERAL (optype))
2516 return operandFromLit (-floatFromVal (op->operand.valOperand));
2518 ic = newiCode (UNARYMINUS, op, NULL);
2519 IC_RESULT (ic) = newiTempOperand (optype, 0);
2521 return IC_RESULT (ic);
2524 /*-----------------------------------------------------------------*/
2525 /* geniCodeLeftShift - gen i code for left shift */
2526 /*-----------------------------------------------------------------*/
2528 geniCodeLeftShift (operand * left, operand * right)
2532 ic = newiCode (LEFT_OP, left, right);
2533 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2535 return IC_RESULT (ic);
2538 /*-----------------------------------------------------------------*/
2539 /* geniCodeRightShift - gen i code for right shift */
2540 /*-----------------------------------------------------------------*/
2542 geniCodeRightShift (operand * left, operand * right)
2546 ic = newiCode (RIGHT_OP, left, right);
2547 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2549 return IC_RESULT (ic);
2552 /*-----------------------------------------------------------------*/
2553 /* geniCodeLogic- logic code */
2554 /*-----------------------------------------------------------------*/
2556 geniCodeLogic (operand * left, operand * right, int op)
2560 sym_link *rtype = operandType (right);
2561 sym_link *ltype = operandType (left);
2563 /* left is integral type and right is literal then
2564 check if the literal value is within bounds */
2565 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2567 checkConstantRange(ltype,
2568 OP_VALUE(right), "compare operation", 1);
2571 ctype = usualBinaryConversions (&left, &right);
2573 ic = newiCode (op, left, right);
2574 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2576 /* if comparing float
2577 and not a '==' || '!=' || '&&' || '||' (these
2579 if (IS_FLOAT(ctype) &&
2587 return IC_RESULT (ic);
2590 /*-----------------------------------------------------------------*/
2591 /* geniCodeUnary - for a a generic unary operation */
2592 /*-----------------------------------------------------------------*/
2594 geniCodeUnary (operand * op, int oper)
2596 iCode *ic = newiCode (oper, op, NULL);
2598 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2600 return IC_RESULT (ic);
2603 /*-----------------------------------------------------------------*/
2604 /* geniCodeConditional - geniCode for '?' ':' operation */
2605 /*-----------------------------------------------------------------*/
2607 geniCodeConditional (ast * tree,int lvl)
2610 symbol *falseLabel = newiTempLabel (NULL);
2611 symbol *exitLabel = newiTempLabel (NULL);
2612 operand *cond = ast2iCode (tree->left,lvl+1);
2613 operand *true, *false, *result;
2615 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2619 true = ast2iCode (tree->right->left,lvl+1);
2621 /* move the value to a new Operand */
2622 result = newiTempOperand (tree->right->ftype, 0);
2623 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2625 /* generate an unconditional goto */
2626 geniCodeGoto (exitLabel);
2628 /* now for the right side */
2629 geniCodeLabel (falseLabel);
2631 false = ast2iCode (tree->right->right,lvl+1);
2632 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2634 /* create the exit label */
2635 geniCodeLabel (exitLabel);
2640 /*-----------------------------------------------------------------*/
2641 /* geniCodeAssign - generate code for assignment */
2642 /*-----------------------------------------------------------------*/
2644 geniCodeAssign (operand * left, operand * right, int nosupdate)
2647 sym_link *ltype = operandType (left);
2648 sym_link *rtype = operandType (right);
2650 if (!left->isaddr && !IS_ITEMP (left))
2652 werror (E_LVALUE_REQUIRED, "assignment");
2656 /* left is integral type and right is literal then
2657 check if the literal value is within bounds */
2658 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2660 checkConstantRange(ltype,
2661 OP_VALUE(right), "= operation", 0);
2664 /* if the left & right type don't exactly match */
2665 /* if pointer set then make sure the check is
2666 done with the type & not the pointer */
2667 /* then cast rights type to left */
2669 /* first check the type for pointer assignement */
2670 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2671 compareType (ltype, rtype) <= 0)
2673 if (compareType (ltype->next, rtype) < 0)
2674 right = geniCodeCast (ltype->next, right, TRUE);
2676 else if (compareType (ltype, rtype) < 0)
2677 right = geniCodeCast (ltype, right, TRUE);
2679 /* if left is a true symbol & ! volatile
2680 create an assignment to temporary for
2681 the right & then assign this temporary
2682 to the symbol this is SSA . isn't it simple
2683 and folks have published mountains of paper on it */
2684 if (IS_TRUE_SYMOP (left) &&
2685 !isOperandVolatile (left, FALSE) &&
2686 isOperandGlobal (left))
2690 if (IS_TRUE_SYMOP (right))
2691 sym = OP_SYMBOL (right);
2692 ic = newiCode ('=', NULL, right);
2693 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2694 SPIL_LOC (right) = sym;
2698 ic = newiCode ('=', NULL, right);
2699 IC_RESULT (ic) = left;
2702 /* if left isgptr flag is set then support
2703 routine will be required */
2707 ic->nosupdate = nosupdate;
2711 /*-----------------------------------------------------------------*/
2712 /* geniCodeSEParms - generate code for side effecting fcalls */
2713 /*-----------------------------------------------------------------*/
2715 geniCodeSEParms (ast * parms,int lvl)
2720 if (parms->type == EX_OP && parms->opval.op == PARAM)
2722 geniCodeSEParms (parms->left,lvl);
2723 geniCodeSEParms (parms->right,lvl);
2727 /* hack don't like this but too lazy to think of
2729 if (IS_ADDRESS_OF_OP (parms))
2730 parms->left->lvalue = 1;
2732 if (IS_CAST_OP (parms) &&
2733 IS_PTR (parms->ftype) &&
2734 IS_ADDRESS_OF_OP (parms->right))
2735 parms->right->left->lvalue = 1;
2737 parms->opval.oprnd =
2738 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2740 parms->type = EX_OPERAND;
2743 /*-----------------------------------------------------------------*/
2744 /* geniCodeParms - generates parameters */
2745 /*-----------------------------------------------------------------*/
2747 geniCodeParms (ast * parms, value *argVals, int *stack,
2748 sym_link * fetype, symbol * func,int lvl)
2756 if (argVals==NULL) {
2758 argVals=FUNC_ARGS(func->type);
2761 /* if this is a param node then do the left & right */
2762 if (parms->type == EX_OP && parms->opval.op == PARAM)
2764 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2765 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2769 /* get the parameter value */
2770 if (parms->type == EX_OPERAND)
2771 pval = parms->opval.oprnd;
2774 /* maybe this else should go away ?? */
2775 /* hack don't like this but too lazy to think of
2777 if (IS_ADDRESS_OF_OP (parms))
2778 parms->left->lvalue = 1;
2780 if (IS_CAST_OP (parms) &&
2781 IS_PTR (parms->ftype) &&
2782 IS_ADDRESS_OF_OP (parms->right))
2783 parms->right->left->lvalue = 1;
2785 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2788 /* if register parm then make it a send */
2789 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2790 IFFUNC_ISBUILTIN(func->type))
2792 ic = newiCode (SEND, pval, NULL);
2793 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2798 /* now decide whether to push or assign */
2799 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2803 operand *top = operandFromSymbol (argVals->sym);
2804 /* clear useDef and other bitVectors */
2805 OP_USES (top) = OP_DEFS (top) = OP_SYMBOL(top)->clashes = NULL;
2806 geniCodeAssign (top, pval, 1);
2810 sym_link *p = operandType (pval);
2812 ic = newiCode (IPUSH, pval, NULL);
2814 /* update the stack adjustment */
2815 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2820 argVals=argVals->next;
2824 /*-----------------------------------------------------------------*/
2825 /* geniCodeCall - generates temp code for calling */
2826 /*-----------------------------------------------------------------*/
2828 geniCodeCall (operand * left, ast * parms,int lvl)
2832 sym_link *type, *etype;
2835 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2836 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2837 werror (E_FUNCTION_EXPECTED);
2841 /* take care of parameters with side-effecting
2842 function calls in them, this is required to take care
2843 of overlaying function parameters */
2844 geniCodeSEParms (parms,lvl);
2846 /* first the parameters */
2847 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2849 /* now call : if symbol then pcall */
2850 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2851 ic = newiCode (PCALL, left, NULL);
2853 ic = newiCode (CALL, left, NULL);
2855 type = copyLinkChain (operandType (left)->next);
2856 etype = getSpec (type);
2857 SPEC_EXTR (etype) = 0;
2858 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2862 /* stack adjustment after call */
2863 ic->parmBytes = stack;
2868 /*-----------------------------------------------------------------*/
2869 /* geniCodeReceive - generate intermediate code for "receive" */
2870 /*-----------------------------------------------------------------*/
2872 geniCodeReceive (value * args)
2874 /* for all arguments that are passed in registers */
2878 if (IS_REGPARM (args->etype))
2880 operand *opr = operandFromValue (args);
2882 symbol *sym = OP_SYMBOL (opr);
2885 /* we will use it after all optimizations
2886 and before liveRange calculation */
2887 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2890 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2891 options.stackAuto == 0 &&
2892 /* !TARGET_IS_DS390) */
2893 (!(options.model == MODEL_FLAT24)) )
2898 opl = newiTempOperand (args->type, 0);
2900 sym->reqv->key = sym->key;
2901 OP_SYMBOL (sym->reqv)->key = sym->key;
2902 OP_SYMBOL (sym->reqv)->isreqv = 1;
2903 OP_SYMBOL (sym->reqv)->islocal = 0;
2904 SPIL_LOC (sym->reqv) = sym;
2908 ic = newiCode (RECEIVE, NULL, NULL);
2909 currFunc->recvSize = getSize (sym->etype);
2910 IC_RESULT (ic) = opr;
2918 /*-----------------------------------------------------------------*/
2919 /* geniCodeFunctionBody - create the function body */
2920 /*-----------------------------------------------------------------*/
2922 geniCodeFunctionBody (ast * tree,int lvl)
2929 /* reset the auto generation */
2935 func = ast2iCode (tree->left,lvl+1);
2936 fetype = getSpec (operandType (func));
2938 savelineno = lineno;
2939 lineno = OP_SYMBOL (func)->lineDef;
2940 /* create an entry label */
2941 geniCodeLabel (entryLabel);
2942 lineno = savelineno;
2944 /* create a proc icode */
2945 ic = newiCode (FUNCTION, func, NULL);
2946 ic->lineno = OP_SYMBOL (func)->lineDef;
2950 /* for all parameters that are passed
2951 on registers add a "receive" */
2952 geniCodeReceive (tree->values.args);
2954 /* generate code for the body */
2955 ast2iCode (tree->right,lvl+1);
2957 /* create a label for return */
2958 geniCodeLabel (returnLabel);
2960 /* now generate the end proc */
2961 ic = newiCode (ENDFUNCTION, func, NULL);
2966 /*-----------------------------------------------------------------*/
2967 /* geniCodeReturn - gen icode for 'return' statement */
2968 /*-----------------------------------------------------------------*/
2970 geniCodeReturn (operand * op)
2974 /* if the operand is present force an rvalue */
2976 op = geniCodeRValue (op, FALSE);
2978 ic = newiCode (RETURN, op, NULL);
2982 /*-----------------------------------------------------------------*/
2983 /* geniCodeIfx - generates code for extended if statement */
2984 /*-----------------------------------------------------------------*/
2986 geniCodeIfx (ast * tree,int lvl)
2989 operand *condition = ast2iCode (tree->left,lvl+1);
2992 /* if condition is null then exit */
2996 condition = geniCodeRValue (condition, FALSE);
2998 cetype = getSpec (operandType (condition));
2999 /* if the condition is a literal */
3000 if (IS_LITERAL (cetype))
3002 if (floatFromVal (condition->operand.valOperand))
3004 if (tree->trueLabel)
3005 geniCodeGoto (tree->trueLabel);
3011 if (tree->falseLabel)
3012 geniCodeGoto (tree->falseLabel);
3019 if (tree->trueLabel)
3021 ic = newiCodeCondition (condition,
3026 if (tree->falseLabel)
3027 geniCodeGoto (tree->falseLabel);
3031 ic = newiCodeCondition (condition,
3038 ast2iCode (tree->right,lvl+1);
3041 /*-----------------------------------------------------------------*/
3042 /* geniCodeJumpTable - tries to create a jump table for switch */
3043 /*-----------------------------------------------------------------*/
3045 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3047 int min = 0, max = 0, t, cnt = 0;
3054 if (!tree || !caseVals)
3057 /* the criteria for creating a jump table is */
3058 /* all integer numbers between the maximum & minimum must */
3059 /* be present , the maximum value should not exceed 255 */
3060 min = max = (int) floatFromVal (vch = caseVals);
3061 sprintf (buffer, "_case_%d_%d",
3062 tree->values.switchVals.swNum,
3064 addSet (&labels, newiTempLabel (buffer));
3066 /* if there is only one case value then no need */
3067 if (!(vch = vch->next))
3072 if (((t = (int) floatFromVal (vch)) - max) != 1)
3074 sprintf (buffer, "_case_%d_%d",
3075 tree->values.switchVals.swNum,
3077 addSet (&labels, newiTempLabel (buffer));
3083 /* if the number of case statements <= 2 then */
3084 /* it is not economical to create the jump table */
3085 /* since two compares are needed for boundary conditions */
3086 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3089 if (tree->values.switchVals.swDefault)
3090 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3092 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3094 falseLabel = newiTempLabel (buffer);
3096 /* so we can create a jumptable */
3097 /* first we rule out the boundary conditions */
3098 /* if only optimization says so */
3099 if (!optimize.noJTabBoundary)
3101 sym_link *cetype = getSpec (operandType (cond));
3102 /* no need to check the lower bound if
3103 the condition is unsigned & minimum value is zero */
3104 if (!(min == 0 && SPEC_USIGN (cetype)))
3106 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3107 ic = newiCodeCondition (boundary, falseLabel, NULL);
3111 /* now for upper bounds */
3112 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3113 ic = newiCodeCondition (boundary, falseLabel, NULL);
3117 /* if the min is not zero then we no make it zero */
3120 cond = geniCodeSubtract (cond, operandFromLit (min));
3121 setOperandType (cond, UCHARTYPE);
3124 /* now create the jumptable */
3125 ic = newiCode (JUMPTABLE, NULL, NULL);
3126 IC_JTCOND (ic) = cond;
3127 IC_JTLABELS (ic) = labels;
3132 /*-----------------------------------------------------------------*/
3133 /* geniCodeSwitch - changes a switch to a if statement */
3134 /*-----------------------------------------------------------------*/
3136 geniCodeSwitch (ast * tree,int lvl)
3139 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3140 value *caseVals = tree->values.switchVals.swVals;
3141 symbol *trueLabel, *falseLabel;
3143 /* if we can make this a jump table */
3144 if (geniCodeJumpTable (cond, caseVals, tree))
3145 goto jumpTable; /* no need for the comparison */
3147 /* for the cases defined do */
3151 operand *compare = geniCodeLogic (cond,
3152 operandFromValue (caseVals),
3155 sprintf (buffer, "_case_%d_%d",
3156 tree->values.switchVals.swNum,
3157 (int) floatFromVal (caseVals));
3158 trueLabel = newiTempLabel (buffer);
3160 ic = newiCodeCondition (compare, trueLabel, NULL);
3162 caseVals = caseVals->next;
3167 /* if default is present then goto break else break */
3168 if (tree->values.switchVals.swDefault)
3169 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3171 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3173 falseLabel = newiTempLabel (buffer);
3174 geniCodeGoto (falseLabel);
3177 ast2iCode (tree->right,lvl+1);
3180 /*-----------------------------------------------------------------*/
3181 /* geniCodeInline - intermediate code for inline assembler */
3182 /*-----------------------------------------------------------------*/
3184 geniCodeInline (ast * tree)
3188 ic = newiCode (INLINEASM, NULL, NULL);
3189 IC_INLINE (ic) = tree->values.inlineasm;
3193 /*-----------------------------------------------------------------*/
3194 /* geniCodeArrayInit - intermediate code for array initializer */
3195 /*-----------------------------------------------------------------*/
3197 geniCodeArrayInit (ast * tree, operand *array)
3201 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3202 ic = newiCode (ARRAYINIT, array, NULL);
3203 IC_ARRAYILIST (ic) = tree->values.constlist;
3205 operand *left=newOperand(), *right=newOperand();
3206 left->type=right->type=SYMBOL;
3207 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3208 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3209 ic = newiCode (ARRAYINIT, left, right);
3214 /*-----------------------------------------------------------------*/
3215 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3216 /* particular case. Ie : assigning or dereferencing array or ptr */
3217 /*-----------------------------------------------------------------*/
3218 set * lvaluereqSet = NULL;
3219 typedef struct lvalItem
3226 /*-----------------------------------------------------------------*/
3227 /* addLvaluereq - add a flag for lvalreq for current ast level */
3228 /*-----------------------------------------------------------------*/
3229 void addLvaluereq(int lvl)
3231 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3234 addSetHead(&lvaluereqSet,lpItem);
3237 /*-----------------------------------------------------------------*/
3238 /* delLvaluereq - del a flag for lvalreq for current ast level */
3239 /*-----------------------------------------------------------------*/
3243 lpItem = getSet(&lvaluereqSet);
3244 if(lpItem) Safe_free(lpItem);
3246 /*-----------------------------------------------------------------*/
3247 /* clearLvaluereq - clear lvalreq flag */
3248 /*-----------------------------------------------------------------*/
3249 void clearLvaluereq()
3252 lpItem = peekSet(lvaluereqSet);
3253 if(lpItem) lpItem->req = 0;
3255 /*-----------------------------------------------------------------*/
3256 /* getLvaluereq - get the last lvalreq level */
3257 /*-----------------------------------------------------------------*/
3258 int getLvaluereqLvl()
3261 lpItem = peekSet(lvaluereqSet);
3262 if(lpItem) return lpItem->lvl;
3265 /*-----------------------------------------------------------------*/
3266 /* isLvaluereq - is lvalreq valid for this level ? */
3267 /*-----------------------------------------------------------------*/
3268 int isLvaluereq(int lvl)
3271 lpItem = peekSet(lvaluereqSet);
3272 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3276 /*-----------------------------------------------------------------*/
3277 /* ast2iCode - creates an icodeList from an ast */
3278 /*-----------------------------------------------------------------*/
3280 ast2iCode (ast * tree,int lvl)
3282 operand *left = NULL;
3283 operand *right = NULL;
3286 /* set the global variables for filename & line number */
3288 filename = tree->filename;
3290 lineno = tree->lineno;
3292 block = tree->block;
3294 scopeLevel = tree->level;
3296 if (tree->type == EX_VALUE)
3297 return operandFromValue (tree->opval.val);
3299 if (tree->type == EX_LINK)
3300 return operandFromLink (tree->opval.lnk);
3302 /* if we find a nullop */
3303 if (tree->type == EX_OP &&
3304 (tree->opval.op == NULLOP ||
3305 tree->opval.op == BLOCK))
3307 ast2iCode (tree->left,lvl+1);
3308 ast2iCode (tree->right,lvl+1);
3312 /* special cases for not evaluating */
3313 if (tree->opval.op != ':' &&
3314 tree->opval.op != '?' &&
3315 tree->opval.op != CALL &&
3316 tree->opval.op != IFX &&
3317 tree->opval.op != LABEL &&
3318 tree->opval.op != GOTO &&
3319 tree->opval.op != SWITCH &&
3320 tree->opval.op != FUNCTION &&
3321 tree->opval.op != INLINEASM)
3324 if (IS_ASSIGN_OP (tree->opval.op) ||
3325 IS_DEREF_OP (tree) ||
3326 (tree->opval.op == '&' && !tree->right) ||
3327 tree->opval.op == PTR_OP)
3330 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3331 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3334 left = operandFromAst (tree->left,lvl);
3336 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3337 left = geniCodeRValue (left, TRUE);
3341 left = operandFromAst (tree->left,lvl);
3343 if (tree->opval.op == INC_OP ||
3344 tree->opval.op == DEC_OP)
3347 right = operandFromAst (tree->right,lvl);
3352 right = operandFromAst (tree->right,lvl);
3356 /* now depending on the type of operand */
3357 /* this will be a biggy */
3358 switch (tree->opval.op)
3361 case '[': /* array operation */
3363 //sym_link *ltype = operandType (left);
3364 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3365 left = geniCodeRValue (left, FALSE);
3366 right = geniCodeRValue (right, TRUE);
3369 return geniCodeArray (left, right,lvl);
3371 case '.': /* structure dereference */
3372 if (IS_PTR (operandType (left)))
3373 left = geniCodeRValue (left, TRUE);
3375 left = geniCodeRValue (left, FALSE);
3377 return geniCodeStruct (left, right, tree->lvalue);
3379 case PTR_OP: /* structure pointer dereference */
3382 pType = operandType (left);
3383 left = geniCodeRValue (left, TRUE);
3385 setOClass (pType, getSpec (operandType (left)));
3388 return geniCodeStruct (left, right, tree->lvalue);
3390 case INC_OP: /* increment operator */
3392 return geniCodePostInc (left);
3394 return geniCodePreInc (right);
3396 case DEC_OP: /* decrement operator */
3398 return geniCodePostDec (left);
3400 return geniCodePreDec (right);
3402 case '&': /* bitwise and or address of operator */
3404 { /* this is a bitwise operator */
3405 left = geniCodeRValue (left, FALSE);
3406 right = geniCodeRValue (right, FALSE);
3407 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3410 return geniCodeAddressOf (left);
3412 case '|': /* bitwise or & xor */
3414 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3415 geniCodeRValue (right, FALSE),
3420 return geniCodeDivision (geniCodeRValue (left, FALSE),
3421 geniCodeRValue (right, FALSE));
3424 return geniCodeModulus (geniCodeRValue (left, FALSE),
3425 geniCodeRValue (right, FALSE));
3428 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3429 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3431 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3435 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3436 geniCodeRValue (right, FALSE));
3438 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3442 return geniCodeAdd (geniCodeRValue (left, FALSE),
3443 geniCodeRValue (right, FALSE),lvl);
3445 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3448 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3449 geniCodeRValue (right, FALSE));
3452 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3453 geniCodeRValue (right, FALSE));
3455 return geniCodeCast (operandType (left),
3456 geniCodeRValue (right, FALSE), FALSE);
3462 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3466 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3467 setOperandType (op, UCHARTYPE);
3478 return geniCodeLogic (geniCodeRValue (left, FALSE),
3479 geniCodeRValue (right, FALSE),
3482 return geniCodeConditional (tree,lvl);
3485 return operandFromLit (getSize (tree->right->ftype));
3489 sym_link *rtype = operandType (right);
3490 sym_link *ltype = operandType (left);
3491 if (IS_PTR (rtype) && IS_ITEMP (right)
3492 && right->isaddr && compareType (rtype->next, ltype) == 1)
3493 right = geniCodeRValue (right, TRUE);
3495 right = geniCodeRValue (right, FALSE);
3497 geniCodeAssign (left, right, 0);
3502 geniCodeAssign (left,
3503 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3505 geniCodeRValue (right, FALSE),FALSE), 0);
3509 geniCodeAssign (left,
3510 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3512 geniCodeRValue (right, FALSE)), 0);
3515 geniCodeAssign (left,
3516 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3518 geniCodeRValue (right, FALSE)), 0);
3521 sym_link *rtype = operandType (right);
3522 sym_link *ltype = operandType (left);
3523 if (IS_PTR (rtype) && IS_ITEMP (right)
3524 && right->isaddr && compareType (rtype->next, ltype) == 1)
3525 right = geniCodeRValue (right, TRUE);
3527 right = geniCodeRValue (right, FALSE);
3530 return geniCodeAssign (left,
3531 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3537 sym_link *rtype = operandType (right);
3538 sym_link *ltype = operandType (left);
3539 if (IS_PTR (rtype) && IS_ITEMP (right)
3540 && right->isaddr && compareType (rtype->next, ltype) == 1)
3542 right = geniCodeRValue (right, TRUE);
3546 right = geniCodeRValue (right, FALSE);
3549 geniCodeAssign (left,
3550 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3556 geniCodeAssign (left,
3557 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3559 geniCodeRValue (right, FALSE)), 0);
3562 geniCodeAssign (left,
3563 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3565 geniCodeRValue (right, FALSE)), 0);
3568 geniCodeAssign (left,
3569 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3571 geniCodeRValue (right, FALSE),
3573 operandType (left)), 0);
3576 geniCodeAssign (left,
3577 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3579 geniCodeRValue (right, FALSE),
3581 operandType (left)), 0);
3584 geniCodeAssign (left,
3585 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3587 geniCodeRValue (right, FALSE),
3589 operandType (left)), 0);
3591 return geniCodeRValue (right, FALSE);
3594 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3597 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3598 return ast2iCode (tree->right,lvl+1);
3601 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3602 return ast2iCode (tree->right,lvl+1);
3605 geniCodeFunctionBody (tree,lvl);
3609 geniCodeReturn (right);
3613 geniCodeIfx (tree,lvl);
3617 geniCodeSwitch (tree,lvl);
3621 geniCodeInline (tree);
3625 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3632 /*-----------------------------------------------------------------*/
3633 /* reverseICChain - gets from the list and creates a linkedlist */
3634 /*-----------------------------------------------------------------*/
3641 while ((loop = getSet (&iCodeChain)))
3653 /*-----------------------------------------------------------------*/
3654 /* iCodeFromAst - given an ast will convert it to iCode */
3655 /*-----------------------------------------------------------------*/
3657 iCodeFromAst (ast * tree)
3659 returnLabel = newiTempLabel ("_return");
3660 entryLabel = newiTempLabel ("_entry");
3662 return reverseiCChain ();