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,
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;
181 #if 0 // temporary disabled, leaving the warning as a reminder
183 sprintf (message, "for %s %s in %s",
184 SPEC_USIGN(ltype) ? "unsigned" : "signed",
185 nounName(ltype), msg);
186 werror (W_CONST_RANGE, message);
194 /*-----------------------------------------------------------------*/
195 /* operandName - returns the name of the operand */
196 /*-----------------------------------------------------------------*/
198 printOperand (operand * op, FILE * file)
215 opetype = getSpec (operandType (op));
216 if (SPEC_NOUN (opetype) == V_FLOAT)
217 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
219 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
220 printTypeChain (operandType (op), file);
227 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}" , */
228 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
230 OP_LIVEFROM (op), OP_LIVETO (op),
231 OP_SYMBOL (op)->stack,
232 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
233 OP_SYMBOL(op)->ruonly
237 printTypeChain (operandType (op), file);
238 if (SPIL_LOC (op) && IS_ITEMP (op))
239 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
244 /* if assigned to registers */
245 if (OP_SYMBOL (op)->nRegs)
247 if (OP_SYMBOL (op)->isspilt)
249 if (!OP_SYMBOL (op)->remat)
250 if (OP_SYMBOL (op)->usl.spillLoc)
251 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
252 OP_SYMBOL (op)->usl.spillLoc->rname :
253 OP_SYMBOL (op)->usl.spillLoc->name));
255 fprintf (file, "[err]");
257 fprintf (file, "[remat]");
263 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
264 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
269 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
270 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
271 /* if assigned to registers */
272 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
276 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
277 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
278 OP_SYMBOL (op)->regs[i]->name :
287 printTypeChain (op->operand.typeOperand, file);
293 fprintf (file, "\n");
298 /*-----------------------------------------------------------------*/
299 /* print functions */
300 /*-----------------------------------------------------------------*/
301 PRINTFUNC (picGetValueAtAddr)
304 printOperand (IC_RESULT (ic), of);
307 printOperand (IC_LEFT (ic), of);
313 PRINTFUNC (picSetValueAtAddr)
317 printOperand (IC_LEFT (ic), of);
318 fprintf (of, "] = ");
319 printOperand (IC_RIGHT (ic), of);
323 PRINTFUNC (picAddrOf)
326 printOperand (IC_RESULT (ic), of);
327 if (IS_ITEMP (IC_LEFT (ic)))
330 fprintf (of, " = &[");
331 printOperand (IC_LEFT (ic), of);
334 if (IS_ITEMP (IC_LEFT (ic)))
335 fprintf (of, " offsetAdd ");
338 printOperand (IC_RIGHT (ic), of);
340 if (IS_ITEMP (IC_LEFT (ic)))
346 PRINTFUNC (picJumpTable)
351 fprintf (of, "%s\t", s);
352 printOperand (IC_JTCOND (ic), of);
354 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
355 sym = setNextItem (IC_JTLABELS (ic)))
356 fprintf (of, "\t\t\t%s\n", sym->name);
359 PRINTFUNC (picGeneric)
362 printOperand (IC_RESULT (ic), of);
364 printOperand (IC_LEFT (ic), of);
365 fprintf (of, " %s ", s);
366 printOperand (IC_RIGHT (ic), of);
370 PRINTFUNC (picGenericOne)
375 printOperand (IC_RESULT (ic), of);
381 fprintf (of, "%s ", s);
382 printOperand (IC_LEFT (ic), of);
385 if (!IC_RESULT (ic) && !IC_LEFT (ic))
394 printOperand (IC_RESULT (ic), of);
396 printOperand (IC_LEFT (ic), of);
397 printOperand (IC_RIGHT (ic), of);
402 PRINTFUNC (picAssign)
406 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
409 printOperand (IC_RESULT (ic), of);
411 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
414 fprintf (of, " %s ", s);
415 printOperand (IC_RIGHT (ic), of);
422 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
428 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
435 printOperand (IC_COND (ic), of);
438 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
441 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
443 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
447 PRINTFUNC (picInline)
449 fprintf (of, "%s", IC_INLINE (ic));
452 PRINTFUNC (picReceive)
454 printOperand (IC_RESULT (ic), of);
455 fprintf (of, " = %s ", s);
456 printOperand (IC_LEFT (ic), of);
460 /*-----------------------------------------------------------------*/
461 /* piCode - prints one iCode */
462 /*-----------------------------------------------------------------*/
464 piCode (void *item, FILE * of)
472 icTab = getTableEntry (ic->op);
473 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
474 ic->filename, ic->lineno,
475 ic->seq, ic->key, ic->depth, ic->supportRtn);
476 icTab->iCodePrint (of, ic, icTab->printName);
482 printiCChain(ic,stdout);
484 /*-----------------------------------------------------------------*/
485 /* printiCChain - prints intermediate code for humans */
486 /*-----------------------------------------------------------------*/
488 printiCChain (iCode * icChain, FILE * of)
495 for (loop = icChain; loop; loop = loop->next)
497 if ((icTab = getTableEntry (loop->op)))
499 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
500 loop->filename, loop->lineno,
501 loop->seq, loop->key, loop->depth, loop->supportRtn);
503 icTab->iCodePrint (of, loop, icTab->printName);
509 /*-----------------------------------------------------------------*/
510 /* newOperand - allocate, init & return a new iCode */
511 /*-----------------------------------------------------------------*/
517 op = Safe_alloc ( sizeof (operand));
523 /*-----------------------------------------------------------------*/
524 /* newiCode - create and return a new iCode entry initialised */
525 /*-----------------------------------------------------------------*/
527 newiCode (int op, operand * left, operand * right)
531 ic = Safe_alloc ( sizeof (iCode));
534 ic->filename = filename;
536 ic->level = scopeLevel;
538 ic->key = iCodeKey++;
540 IC_RIGHT (ic) = right;
545 /*-----------------------------------------------------------------*/
546 /* newiCode for conditional statements */
547 /*-----------------------------------------------------------------*/
549 newiCodeCondition (operand * condition,
555 if (IS_VOID(operandType(condition))) {
556 werror(E_VOID_VALUE_USED);
559 ic = newiCode (IFX, NULL, NULL);
560 IC_COND (ic) = condition;
561 IC_TRUE (ic) = trueLabel;
562 IC_FALSE (ic) = falseLabel;
566 /*-----------------------------------------------------------------*/
567 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
568 /*-----------------------------------------------------------------*/
570 newiCodeLabelGoto (int op, symbol * label)
574 ic = newiCode (op, NULL, NULL);
576 ic->argLabel.label = label;
578 IC_RIGHT (ic) = NULL;
579 IC_RESULT (ic) = NULL;
583 /*-----------------------------------------------------------------*/
584 /* newiTemp - allocate & return a newItemp Variable */
585 /*-----------------------------------------------------------------*/
592 sprintf (buffer, "%s", s);
594 sprintf (buffer, "iTemp%d", iTempNum++);
595 itmp = newSymbol (buffer, 1);
596 strcpy (itmp->rname, itmp->name);
602 /*-----------------------------------------------------------------*/
603 /* newiTempLabel - creates a temp variable label */
604 /*-----------------------------------------------------------------*/
606 newiTempLabel (char *s)
610 /* check if this alredy exists */
611 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
615 itmplbl = newSymbol (s, 1);
618 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
619 itmplbl = newSymbol (buffer, 1);
624 itmplbl->key = labelKey++;
625 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
629 /*-----------------------------------------------------------------*/
630 /* newiTempPreheaderLabel - creates a new preheader label */
631 /*-----------------------------------------------------------------*/
633 newiTempPreheaderLabel ()
637 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
638 itmplbl = newSymbol (buffer, 1);
642 itmplbl->key = labelKey++;
643 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
648 /*-----------------------------------------------------------------*/
649 /* initiCode - initialises some iCode related stuff */
650 /*-----------------------------------------------------------------*/
657 /*-----------------------------------------------------------------*/
658 /* copyiCode - make a copy of the iCode given */
659 /*-----------------------------------------------------------------*/
661 copyiCode (iCode * ic)
663 iCode *nic = newiCode (ic->op, NULL, NULL);
665 nic->lineno = ic->lineno;
666 nic->filename = ic->filename;
667 nic->block = ic->block;
668 nic->level = ic->level;
669 nic->parmBytes = ic->parmBytes;
671 /* deal with the special cases first */
675 IC_COND (nic) = operandFromOperand (IC_COND (ic));
676 IC_TRUE (nic) = IC_TRUE (ic);
677 IC_FALSE (nic) = IC_FALSE (ic);
681 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
682 IC_JTLABELS (nic) = IC_JTLABELS (ic);
687 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
688 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
692 IC_INLINE (nic) = IC_INLINE (ic);
696 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
700 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
701 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
702 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
708 /*-----------------------------------------------------------------*/
709 /* getTableEntry - gets the table entry for the given operator */
710 /*-----------------------------------------------------------------*/
712 getTableEntry (int oper)
716 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
717 if (oper == codeTable[i].icode)
718 return &codeTable[i];
723 /*-----------------------------------------------------------------*/
724 /* newiTempOperand - new intermediate temp operand */
725 /*-----------------------------------------------------------------*/
727 newiTempOperand (sym_link * type, char throwType)
730 operand *op = newOperand ();
734 itmp = newiTemp (NULL);
736 etype = getSpec (type);
738 if (IS_LITERAL (etype))
741 /* copy the type information */
743 itmp->etype = getSpec (itmp->type = (throwType ? type :
744 copyLinkChain (type)));
745 if (IS_LITERAL (itmp->etype))
747 SPEC_SCLS (itmp->etype) = S_REGISTER;
748 SPEC_OCLS (itmp->etype) = reg;
751 op->operand.symOperand = itmp;
752 op->key = itmp->key = ++operandKey;
756 /*-----------------------------------------------------------------*/
757 /* operandType - returns the type chain for an operand */
758 /*-----------------------------------------------------------------*/
760 operandType (operand * op)
762 /* depending on type of operand */
767 return op->operand.valOperand->type;
770 return op->operand.symOperand->type;
773 return op->operand.typeOperand;
775 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
776 " operand type not known ");
777 assert (0); /* should never come here */
778 /* Just to keep the compiler happy */
779 return (sym_link *) 0;
783 /*-----------------------------------------------------------------*/
784 /* isParamterToCall - will return 1 if op is a parameter to args */
785 /*-----------------------------------------------------------------*/
787 isParameterToCall (value * args, operand * op)
794 isSymbolEqual (op->operand.symOperand, tval->sym))
801 /*-----------------------------------------------------------------*/
802 /* isOperandGlobal - return 1 if operand is a global variable */
803 /*-----------------------------------------------------------------*/
805 isOperandGlobal (operand * op)
813 if (op->type == SYMBOL &&
814 (op->operand.symOperand->level == 0 ||
815 IS_STATIC (op->operand.symOperand->etype) ||
816 IS_EXTERN (op->operand.symOperand->etype))
823 /*-----------------------------------------------------------------*/
824 /* isOperandVolatile - return 1 if the operand is volatile */
825 /*-----------------------------------------------------------------*/
827 isOperandVolatile (operand * op, bool chkTemp)
832 if (IS_ITEMP (op) && !chkTemp)
835 opetype = getSpec (optype = operandType (op));
837 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
840 if (IS_VOLATILE (opetype))
845 /*-----------------------------------------------------------------*/
846 /* isOperandLiteral - returns 1 if an operand contains a literal */
847 /*-----------------------------------------------------------------*/
849 isOperandLiteral (operand * op)
856 opetype = getSpec (operandType (op));
858 if (IS_LITERAL (opetype))
864 /*-----------------------------------------------------------------*/
865 /* isOperandInFarSpace - will return true if operand is in farSpace */
866 /*-----------------------------------------------------------------*/
868 isOperandInFarSpace (operand * op)
878 if (!IS_TRUE_SYMOP (op))
881 etype = SPIL_LOC (op)->etype;
887 etype = getSpec (operandType (op));
889 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
892 /*------------------------------------------------------------------*/
893 /* isOperandInDirSpace - will return true if operand is in dirSpace */
894 /*------------------------------------------------------------------*/
896 isOperandInDirSpace (operand * op)
906 if (!IS_TRUE_SYMOP (op))
909 etype = SPIL_LOC (op)->etype;
915 etype = getSpec (operandType (op));
917 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
920 /*-----------------------------------------------------------------*/
921 /* isOperandOnStack - will return true if operand is on stack */
922 /*-----------------------------------------------------------------*/
925 isOperandOnStack (operand * op)
935 etype = getSpec (operandType (op));
937 return ((IN_STACK (etype)) ? TRUE : FALSE);
941 isOperandOnStack (operand * op)
951 etype = getSpec (operandType (op));
952 if (IN_STACK (etype) ||
953 OP_SYMBOL(op)->onStack ||
954 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
961 /*-----------------------------------------------------------------*/
962 /* operandLitValue - literal value of an operand */
963 /*-----------------------------------------------------------------*/
965 operandLitValue (operand * op)
967 assert (isOperandLiteral (op));
969 return floatFromVal (op->operand.valOperand);
972 /*-----------------------------------------------------------------*/
973 /* getBuiltInParms - returns parameters to a builtin functions */
974 /*-----------------------------------------------------------------*/
975 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
980 /* builtin functions uses only SEND for parameters */
981 while (ic->op != CALL) {
982 assert(ic->op == SEND && ic->builtinSEND);
983 ic->generated = 1; /* mark the icode as generated */
984 parms[*pcount] = IC_LEFT(ic);
990 /* make sure this is a builtin function call */
991 assert(IS_SYMOP(IC_LEFT(ic)));
992 ftype = operandType(IC_LEFT(ic));
993 assert(IFFUNC_ISBUILTIN(ftype));
997 /*-----------------------------------------------------------------*/
998 /* operandOperation - perforoms operations on operands */
999 /*-----------------------------------------------------------------*/
1001 operandOperation (operand * left, operand * right,
1002 int op, sym_link * type)
1004 sym_link *let , *ret=NULL;
1005 operand *retval = (operand *) 0;
1007 assert (isOperandLiteral (left));
1008 let = getSpec(operandType(left));
1010 assert (isOperandLiteral (right));
1011 ret = getSpec(operandType(left));
1017 retval = operandFromValue (valCastLiteral (type,
1018 operandLitValue (left) +
1019 operandLitValue (right)));
1022 retval = operandFromValue (valCastLiteral (type,
1023 operandLitValue (left) -
1024 operandLitValue (right)));
1027 retval = operandFromValue (valCastLiteral (type,
1028 operandLitValue (left) *
1029 operandLitValue (right)));
1032 if ((unsigned long) operandLitValue (right) == 0)
1034 werror (E_DIVIDE_BY_ZERO);
1039 retval = operandFromValue (valCastLiteral (type,
1040 operandLitValue (left) /
1041 operandLitValue (right)));
1044 if ((unsigned long) operandLitValue (right) == 0) {
1045 werror (E_DIVIDE_BY_ZERO);
1049 retval = operandFromLit ((SPEC_USIGN(let) ?
1050 (unsigned long) operandLitValue (left) :
1051 (long) operandLitValue (left)) %
1053 (unsigned long) operandLitValue (right) :
1054 (long) operandLitValue (right)));
1058 retval = operandFromLit ((SPEC_USIGN(let) ?
1059 (unsigned long) operandLitValue (left) :
1060 (long) operandLitValue (left)) <<
1062 (unsigned long) operandLitValue (right) :
1063 (long) operandLitValue (right)));
1066 retval = operandFromLit ((SPEC_USIGN(let) ?
1067 (unsigned long) operandLitValue (left) :
1068 (long) operandLitValue (left)) >>
1070 (unsigned long) operandLitValue (right) :
1071 (long) operandLitValue (right)));
1074 retval = operandFromLit (operandLitValue (left) ==
1075 operandLitValue (right));
1078 retval = operandFromLit (operandLitValue (left) <
1079 operandLitValue (right));
1082 retval = operandFromLit (operandLitValue (left) <=
1083 operandLitValue (right));
1086 retval = operandFromLit (operandLitValue (left) !=
1087 operandLitValue (right));
1090 retval = operandFromLit (operandLitValue (left) >
1091 operandLitValue (right));
1094 retval = operandFromLit (operandLitValue (left) >=
1095 operandLitValue (right));
1098 retval = operandFromLit ((long)operandLitValue(left) &
1099 (long)operandLitValue(right));
1102 retval = operandFromLit ((long)operandLitValue (left) |
1103 (long)operandLitValue (right));
1106 retval = operandFromLit ((long)operandLitValue (left) ^
1107 (long)operandLitValue (right));
1110 retval = operandFromLit (operandLitValue (left) &&
1111 operandLitValue (right));
1114 retval = operandFromLit (operandLitValue (left) ||
1115 operandLitValue (right));
1119 long i = (long) operandLitValue (left);
1121 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1127 long i = (long) operandLitValue (left);
1129 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1135 retval = operandFromLit (-1 * operandLitValue (left));
1139 retval = operandFromLit (~((long) operandLitValue (left)));
1143 retval = operandFromLit (!operandLitValue (left));
1147 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1148 " operandOperation invalid operator ");
1156 /*-----------------------------------------------------------------*/
1157 /* isOperandEqual - compares two operand & return 1 if they r = */
1158 /*-----------------------------------------------------------------*/
1160 isOperandEqual (operand * left, operand * right)
1162 /* if the pointers are equal then they are equal */
1166 /* if either of them null then false */
1167 if (!left || !right)
1170 if (left->type != right->type)
1173 if (IS_SYMOP (left) && IS_SYMOP (right))
1174 return left->key == right->key;
1176 /* if types are the same */
1180 return isSymbolEqual (left->operand.symOperand,
1181 right->operand.symOperand);
1183 return (floatFromVal (left->operand.valOperand) ==
1184 floatFromVal (right->operand.valOperand));
1186 if (compareType (left->operand.typeOperand,
1187 right->operand.typeOperand) == 1)
1194 /*-------------------------------------------------------------------*/
1195 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1196 /*-------------------------------------------------------------------*/
1198 isiCodeEqual (iCode * left, iCode * right)
1200 /* if the same pointer */
1204 /* if either of them null */
1205 if (!left || !right)
1208 /* if operand are the same */
1209 if (left->op == right->op)
1212 /* compare all the elements depending on type */
1213 if (left->op != IFX)
1215 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1217 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1223 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1225 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1227 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1236 /*-----------------------------------------------------------------*/
1237 /* newiTempFromOp - create a temp Operand with same attributes */
1238 /*-----------------------------------------------------------------*/
1240 newiTempFromOp (operand * op)
1250 nop = newiTempOperand (operandType (op), TRUE);
1251 nop->isaddr = op->isaddr;
1252 nop->isvolatile = op->isvolatile;
1253 nop->isGlobal = op->isGlobal;
1254 nop->isLiteral = op->isLiteral;
1255 nop->usesDefs = op->usesDefs;
1256 nop->isParm = op->isParm;
1260 /*-----------------------------------------------------------------*/
1261 /* operand from operand - creates an operand holder for the type */
1262 /*-----------------------------------------------------------------*/
1264 operandFromOperand (operand * op)
1270 nop = newOperand ();
1271 nop->type = op->type;
1272 nop->isaddr = op->isaddr;
1274 nop->isvolatile = op->isvolatile;
1275 nop->isGlobal = op->isGlobal;
1276 nop->isLiteral = op->isLiteral;
1277 nop->usesDefs = op->usesDefs;
1278 nop->isParm = op->isParm;
1283 nop->operand.symOperand = op->operand.symOperand;
1286 nop->operand.valOperand = op->operand.valOperand;
1289 nop->operand.typeOperand = op->operand.typeOperand;
1296 /*-----------------------------------------------------------------*/
1297 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1298 /*-----------------------------------------------------------------*/
1300 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1302 operand *nop = operandFromOperand (op);
1304 if (nop->type == SYMBOL)
1306 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1307 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1313 /*-----------------------------------------------------------------*/
1314 /* operandFromSymbol - creates an operand from a symbol */
1315 /*-----------------------------------------------------------------*/
1317 operandFromSymbol (symbol * sym)
1322 /* if the symbol's type is a literal */
1323 /* then it is an enumerator type */
1324 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1325 return operandFromValue (valFromType (sym->etype));
1328 sym->key = ++operandKey;
1330 /* if this an implicit variable, means struct/union */
1331 /* member so just return it */
1332 if (sym->implicit || IS_FUNC (sym->type))
1336 op->operand.symOperand = sym;
1338 op->isvolatile = isOperandVolatile (op, TRUE);
1339 op->isGlobal = isOperandGlobal (op);
1343 /* under the following conditions create a
1344 register equivalent for a local symbol */
1345 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1346 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1347 (!(options.model == MODEL_FLAT24)) ) &&
1348 options.stackAuto == 0)
1351 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1352 !IS_FUNC (sym->type) && /* not a function */
1353 !sym->_isparm && /* not a parameter */
1354 sym->level && /* is a local variable */
1355 !sym->addrtaken && /* whose address has not been taken */
1356 !sym->reqv && /* does not already have a reg equivalence */
1357 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1358 !IS_STATIC (sym->etype) && /* and not declared static */
1359 !sym->islbl && /* not a label */
1360 ok && /* farspace check */
1361 !IS_BITVAR (sym->etype) /* not a bit variable */
1365 /* we will use it after all optimizations
1366 and before liveRange calculation */
1367 sym->reqv = newiTempOperand (sym->type, 0);
1368 sym->reqv->key = sym->key;
1369 OP_SYMBOL (sym->reqv)->key = sym->key;
1370 OP_SYMBOL (sym->reqv)->isreqv = 1;
1371 OP_SYMBOL (sym->reqv)->islocal = 1;
1372 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1373 SPIL_LOC (sym->reqv) = sym;
1376 if (!IS_AGGREGATE (sym->type))
1380 op->operand.symOperand = sym;
1383 op->isvolatile = isOperandVolatile (op, TRUE);
1384 op->isGlobal = isOperandGlobal (op);
1385 op->isPtr = IS_PTR (operandType (op));
1386 op->isParm = sym->_isparm;
1391 /* itemp = &[_symbol] */
1393 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1394 IC_LEFT (ic)->type = SYMBOL;
1395 IC_LEFT (ic)->operand.symOperand = sym;
1396 IC_LEFT (ic)->key = sym->key;
1397 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1398 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1399 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1402 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1403 if (IS_ARRAY (sym->type))
1405 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1406 IC_RESULT (ic)->isaddr = 0;
1409 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1413 return IC_RESULT (ic);
1416 /*-----------------------------------------------------------------*/
1417 /* operandFromValue - creates an operand from value */
1418 /*-----------------------------------------------------------------*/
1420 operandFromValue (value * val)
1424 /* if this is a symbol then do the symbol thing */
1426 return operandFromSymbol (val->sym);
1428 /* this is not a symbol */
1431 op->operand.valOperand = val;
1432 op->isLiteral = isOperandLiteral (op);
1436 /*-----------------------------------------------------------------*/
1437 /* operandFromLink - operand from typeChain */
1438 /*-----------------------------------------------------------------*/
1440 operandFromLink (sym_link * type)
1444 /* operand from sym_link */
1450 op->operand.typeOperand = copyLinkChain (type);
1454 /*-----------------------------------------------------------------*/
1455 /* operandFromLit - makes an operand from a literal value */
1456 /*-----------------------------------------------------------------*/
1458 operandFromLit (double i)
1460 return operandFromValue (valueFromLit (i));
1463 /*-----------------------------------------------------------------*/
1464 /* operandFromAst - creates an operand from an ast */
1465 /*-----------------------------------------------------------------*/
1467 operandFromAst (ast * tree,int lvl)
1473 /* depending on type do */
1477 return ast2iCode (tree,lvl+1);
1481 return operandFromValue (tree->opval.val);
1485 return operandFromLink (tree->opval.lnk);
1489 /* Just to keep the comiler happy */
1490 return (operand *) 0;
1493 /*-----------------------------------------------------------------*/
1494 /* setOperandType - sets the operand's type to the given type */
1495 /*-----------------------------------------------------------------*/
1497 setOperandType (operand * op, sym_link * type)
1499 /* depending on the type of operand */
1504 op->operand.valOperand->etype =
1505 getSpec (op->operand.valOperand->type =
1506 copyLinkChain (type));
1510 if (op->operand.symOperand->isitmp)
1511 op->operand.symOperand->etype =
1512 getSpec (op->operand.symOperand->type =
1513 copyLinkChain (type));
1515 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1516 "attempt to modify type of source");
1520 op->operand.typeOperand = copyLinkChain (type);
1525 /*-----------------------------------------------------------------*/
1526 /* Get size in byte of ptr need to access an array */
1527 /*-----------------------------------------------------------------*/
1529 getArraySizePtr (operand * op)
1531 sym_link *ltype = operandType(op);
1535 int size = getSize(ltype);
1536 return(IS_GENPTR(ltype)?(size-1):size);
1541 sym_link *letype = getSpec(ltype);
1542 switch (PTR_TYPE (SPEC_OCLS (letype)))
1554 return (GPTRSIZE-1);
1563 /*-----------------------------------------------------------------*/
1564 /* perform "usual unary conversions" */
1565 /*-----------------------------------------------------------------*/
1567 usualUnaryConversions (operand * op)
1569 if (IS_INTEGRAL (operandType (op)))
1571 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1574 return geniCodeCast (INTTYPE, op, TRUE);
1580 /*-----------------------------------------------------------------*/
1581 /* perform "usual binary conversions" */
1582 /*-----------------------------------------------------------------*/
1584 usualBinaryConversions (operand ** op1, operand ** op2)
1587 sym_link *rtype = operandType (*op2);
1588 sym_link *ltype = operandType (*op1);
1590 ctype = computeType (ltype, rtype);
1591 *op1 = geniCodeCast (ctype, *op1, TRUE);
1592 *op2 = geniCodeCast (ctype, *op2, TRUE);
1597 /*-----------------------------------------------------------------*/
1598 /* geniCodeValueAtAddress - generate intermeditate code for value */
1600 /*-----------------------------------------------------------------*/
1602 geniCodeRValue (operand * op, bool force)
1605 sym_link *type = operandType (op);
1606 sym_link *etype = getSpec (type);
1608 /* if this is an array & already */
1609 /* an address then return this */
1610 if (IS_AGGREGATE (type) ||
1611 (IS_PTR (type) && !force && !op->isaddr))
1612 return operandFromOperand (op);
1614 /* if this is not an address then must be */
1615 /* rvalue already so return this one */
1619 /* if this is not a temp symbol then */
1620 if (!IS_ITEMP (op) &&
1622 !IN_FARSPACE (SPEC_OCLS (etype)))
1624 op = operandFromOperand (op);
1629 if (IS_SPEC (type) &&
1630 IS_TRUE_SYMOP (op) &&
1631 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1632 /* TARGET_IS_DS390)) */
1633 (options.model == MODEL_FLAT24) ))
1635 op = operandFromOperand (op);
1640 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1641 if (IS_PTR (type) && op->isaddr && force)
1644 type = copyLinkChain (type);
1646 IC_RESULT (ic) = newiTempOperand (type, 1);
1647 IC_RESULT (ic)->isaddr = 0;
1649 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1653 return IC_RESULT (ic);
1656 /*-----------------------------------------------------------------*/
1657 /* geniCodeCast - changes the value from one type to another */
1658 /*-----------------------------------------------------------------*/
1660 geniCodeCast (sym_link * type, operand * op, bool implicit)
1664 sym_link *opetype = getSpec (optype = operandType (op));
1668 /* one of them has size zero then error */
1669 if (IS_VOID (optype))
1671 werror (E_CAST_ZERO);
1675 /* if the operand is already the desired type then do nothing */
1676 if (compareType (type, optype) == 1)
1679 /* if this is a literal then just change the type & return */
1680 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1681 return operandFromValue (valCastLiteral (type,
1682 operandLitValue (op)));
1684 /* if casting to/from pointers, do some checking */
1685 if (IS_PTR(type)) { // to a pointer
1686 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1687 if (IS_INTEGRAL(optype)) {
1688 // maybe this is NULL, than it's ok.
1689 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1690 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1691 // no way to set the storage
1692 if (IS_LITERAL(optype)) {
1693 werror(E_LITERAL_GENERIC);
1696 werror(E_NONPTR2_GENPTR);
1699 } else if (implicit) {
1700 werror(W_INTEGRAL2PTR_NOCAST);
1705 // shouldn't do that with float, array or structure unless to void
1706 if (!IS_VOID(getSpec(type)) &&
1707 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1708 werror(E_INCOMPAT_TYPES);
1712 } else { // from a pointer to a pointer
1713 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1714 // if not a pointer to a function
1715 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1716 if (implicit) { // if not to generic, they have to match
1717 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1718 werror(E_INCOMPAT_PTYPES);
1725 } else { // to a non pointer
1726 if (IS_PTR(optype)) { // from a pointer
1727 if (implicit) { // sneaky
1728 if (IS_INTEGRAL(type)) {
1729 werror(W_PTR2INTEGRAL_NOCAST);
1731 } else { // shouldn't do that with float, array or structure
1732 werror(E_INCOMPAT_TYPES);
1739 printFromToType (optype, type);
1742 /* if they are the same size create an assignment */
1743 if (getSize (type) == getSize (optype) &&
1744 !IS_BITFIELD (type) &&
1746 !IS_FLOAT (optype) &&
1747 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1748 (!IS_SPEC (type) && !IS_SPEC (optype))))
1751 ic = newiCode ('=', NULL, op);
1752 IC_RESULT (ic) = newiTempOperand (type, 0);
1753 SPIL_LOC (IC_RESULT (ic)) =
1754 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1755 IC_RESULT (ic)->isaddr = 0;
1759 ic = newiCode (CAST, operandFromLink (type),
1760 geniCodeRValue (op, FALSE));
1762 IC_RESULT (ic) = newiTempOperand (type, 0);
1765 /* preserve the storage class & output class */
1766 /* of the original variable */
1767 restype = getSpec (operandType (IC_RESULT (ic)));
1768 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1769 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1772 return IC_RESULT (ic);
1775 /*-----------------------------------------------------------------*/
1776 /* geniCodeLabel - will create a Label */
1777 /*-----------------------------------------------------------------*/
1779 geniCodeLabel (symbol * label)
1783 ic = newiCodeLabelGoto (LABEL, label);
1787 /*-----------------------------------------------------------------*/
1788 /* geniCodeGoto - will create a Goto */
1789 /*-----------------------------------------------------------------*/
1791 geniCodeGoto (symbol * label)
1795 ic = newiCodeLabelGoto (GOTO, label);
1799 /*-----------------------------------------------------------------*/
1800 /* geniCodeMultiply - gen intermediate code for multiplication */
1801 /*-----------------------------------------------------------------*/
1803 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1810 /* if they are both literal then we know the result */
1811 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1812 return operandFromValue (valMult (left->operand.valOperand,
1813 right->operand.valOperand));
1815 if (IS_LITERAL(retype)) {
1816 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1819 resType = usualBinaryConversions (&left, &right);
1821 rtype = operandType (right);
1822 retype = getSpec (rtype);
1823 ltype = operandType (left);
1824 letype = getSpec (ltype);
1828 SPEC_NOUN(getSpec(resType))=V_INT;
1831 /* if the right is a literal & power of 2 */
1832 /* then make it a left shift */
1833 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1834 efficient in most cases than 2 bytes result = 2 bytes << literal
1835 if port has 1 byte muldiv */
1836 if (p2 && !IS_FLOAT (letype) &&
1837 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1838 (port->support.muldiv == 1)))
1840 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1842 /* LEFT_OP need same size for left and result, */
1843 left = geniCodeCast (resType, left, TRUE);
1844 ltype = operandType (left);
1846 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1850 ic = newiCode ('*', left, right); /* normal multiplication */
1851 /* if the size left or right > 1 then support routine */
1852 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1856 IC_RESULT (ic) = newiTempOperand (resType, 1);
1859 return IC_RESULT (ic);
1862 /*-----------------------------------------------------------------*/
1863 /* geniCodeDivision - gen intermediate code for division */
1864 /*-----------------------------------------------------------------*/
1866 geniCodeDivision (operand * left, operand * right)
1871 sym_link *rtype = operandType (right);
1872 sym_link *retype = getSpec (rtype);
1873 sym_link *ltype = operandType (left);
1874 sym_link *letype = getSpec (ltype);
1876 resType = usualBinaryConversions (&left, &right);
1878 /* if the right is a literal & power of 2 */
1879 /* then make it a right shift */
1880 if (IS_LITERAL (retype) &&
1881 !IS_FLOAT (letype) &&
1882 (p2 = powof2 ((unsigned long)
1883 floatFromVal (right->operand.valOperand)))) {
1884 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1888 ic = newiCode ('/', left, right); /* normal division */
1889 /* if the size left or right > 1 then support routine */
1890 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1893 IC_RESULT (ic) = newiTempOperand (resType, 0);
1896 return IC_RESULT (ic);
1898 /*-----------------------------------------------------------------*/
1899 /* geniCodeModulus - gen intermediate code for modulus */
1900 /*-----------------------------------------------------------------*/
1902 geniCodeModulus (operand * left, operand * right)
1908 /* if they are both literal then we know the result */
1909 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1910 return operandFromValue (valMod (left->operand.valOperand,
1911 right->operand.valOperand));
1913 resType = usualBinaryConversions (&left, &right);
1915 /* now they are the same size */
1916 ic = newiCode ('%', left, right);
1918 /* if the size left or right > 1 then support routine */
1919 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1921 IC_RESULT (ic) = newiTempOperand (resType, 0);
1924 return IC_RESULT (ic);
1927 /*-----------------------------------------------------------------*/
1928 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1929 /*-----------------------------------------------------------------*/
1931 geniCodePtrPtrSubtract (operand * left, operand * right)
1937 /* if they are both literals then */
1938 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1940 result = operandFromValue (valMinus (left->operand.valOperand,
1941 right->operand.valOperand));
1945 ic = newiCode ('-', left, right);
1947 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1951 return geniCodeDivision (result,
1952 operandFromLit (getSize (ltype->next)));
1955 /*-----------------------------------------------------------------*/
1956 /* geniCodeSubtract - generates code for subtraction */
1957 /*-----------------------------------------------------------------*/
1959 geniCodeSubtract (operand * left, operand * right)
1966 /* if they both pointers then */
1967 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1968 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1969 return geniCodePtrPtrSubtract (left, right);
1971 /* if they are both literal then we know the result */
1972 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1973 && left->isLiteral && right->isLiteral)
1974 return operandFromValue (valMinus (left->operand.valOperand,
1975 right->operand.valOperand));
1977 /* if left is an array or pointer */
1978 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1980 isarray = left->isaddr;
1981 right = geniCodeMultiply (right,
1982 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1983 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1986 { /* make them the same size */
1987 resType = usualBinaryConversions (&left, &right);
1990 ic = newiCode ('-', left, right);
1992 IC_RESULT (ic) = newiTempOperand (resType, 1);
1993 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1995 /* if left or right is a float */
1996 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2000 return IC_RESULT (ic);
2003 /*-----------------------------------------------------------------*/
2004 /* geniCodeAdd - generates iCode for addition */
2005 /*-----------------------------------------------------------------*/
2007 geniCodeAdd (operand * left, operand * right, int lvl)
2015 /* if left is an array then array access */
2016 if (IS_ARRAY (ltype))
2017 return geniCodeArray (left, right,lvl);
2019 /* if the right side is LITERAL zero */
2020 /* return the left side */
2021 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2024 /* if left is literal zero return right */
2025 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2028 /* if left is a pointer then size */
2031 isarray = left->isaddr;
2032 // there is no need to multiply with 1
2033 if (getSize(ltype->next)!=1) {
2034 size = operandFromLit (getSize (ltype->next));
2035 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2037 resType = copyLinkChain (ltype);
2040 { // make them the same size
2041 resType = usualBinaryConversions (&left, &right);
2044 /* if they are both literals then we know */
2045 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2046 && left->isLiteral && right->isLiteral)
2047 return operandFromValue (valPlus (valFromType (letype),
2048 valFromType (retype)));
2050 ic = newiCode ('+', left, right);
2052 IC_RESULT (ic) = newiTempOperand (resType, 1);
2053 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2055 /* if left or right is a float then support
2057 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2062 return IC_RESULT (ic);
2066 /*-----------------------------------------------------------------*/
2067 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2068 /*-----------------------------------------------------------------*/
2070 aggrToPtr (sym_link * type, bool force)
2076 if (IS_PTR (type) && !force)
2079 etype = getSpec (type);
2083 /* if the output class is generic */
2084 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2085 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2087 /* if the variable was declared a constant */
2088 /* then the pointer points to a constant */
2089 if (IS_CONSTANT (etype))
2090 DCL_PTR_CONST (ptype) = 1;
2092 /* the variable was volatile then pointer to volatile */
2093 if (IS_VOLATILE (etype))
2094 DCL_PTR_VOLATILE (ptype) = 1;
2098 /*-----------------------------------------------------------------*/
2099 /* geniCodeArray2Ptr - array to pointer */
2100 /*-----------------------------------------------------------------*/
2102 geniCodeArray2Ptr (operand * op)
2104 sym_link *optype = operandType (op);
2105 sym_link *opetype = getSpec (optype);
2107 /* set the pointer depending on the storage class */
2108 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2109 DCL_PTR_CONST (optype) = port->mem.code_ro;
2112 /* if the variable was declared a constant */
2113 /* then the pointer points to a constant */
2114 if (IS_CONSTANT (opetype))
2115 DCL_PTR_CONST (optype) = 1;
2117 /* the variable was volatile then pointer to volatile */
2118 if (IS_VOLATILE (opetype))
2119 DCL_PTR_VOLATILE (optype) = 1;
2125 /*-----------------------------------------------------------------*/
2126 /* geniCodeArray - array access */
2127 /*-----------------------------------------------------------------*/
2129 geniCodeArray (operand * left, operand * right,int lvl)
2132 sym_link *ltype = operandType (left);
2136 if (IS_PTR (ltype->next) && left->isaddr)
2138 left = geniCodeRValue (left, FALSE);
2140 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2143 right = geniCodeMultiply (right,
2144 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2146 /* we can check for limits here */
2147 if (isOperandLiteral (right) &&
2150 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2152 werror (E_ARRAY_BOUND);
2153 right = operandFromLit (0);
2156 ic = newiCode ('+', left, right);
2158 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2159 !IS_AGGREGATE (ltype->next) &&
2160 !IS_PTR (ltype->next))
2161 ? ltype : ltype->next), 0);
2163 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2165 return IC_RESULT (ic);
2168 /*-----------------------------------------------------------------*/
2169 /* geniCodeStruct - generates intermediate code for structres */
2170 /*-----------------------------------------------------------------*/
2172 geniCodeStruct (operand * left, operand * right, bool islval)
2175 sym_link *type = operandType (left);
2176 sym_link *etype = getSpec (type);
2178 symbol *element = getStructElement (SPEC_STRUCT (etype),
2179 right->operand.symOperand);
2181 /* add the offset */
2182 ic = newiCode ('+', left, operandFromLit (element->offset));
2184 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2186 /* preserve the storage & output class of the struct */
2187 /* as well as the volatile attribute */
2188 retype = getSpec (operandType (IC_RESULT (ic)));
2189 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2190 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2191 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2193 if (IS_PTR (element->type))
2194 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2196 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2200 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2203 /*-----------------------------------------------------------------*/
2204 /* geniCodePostInc - generate int code for Post increment */
2205 /*-----------------------------------------------------------------*/
2207 geniCodePostInc (operand * op)
2211 sym_link *optype = operandType (op);
2213 operand *rv = (IS_ITEMP (op) ?
2214 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2216 sym_link *rvtype = operandType (rv);
2219 /* if this is not an address we have trouble */
2222 werror (E_LVALUE_REQUIRED, "++");
2226 rOp = newiTempOperand (rvtype, 0);
2227 OP_SYMBOL(rOp)->noSpilLoc = 1;
2230 OP_SYMBOL(rv)->noSpilLoc = 1;
2232 geniCodeAssign (rOp, rv, 0);
2234 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2235 if (IS_FLOAT (rvtype))
2236 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2238 ic = newiCode ('+', rv, operandFromLit (size));
2240 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2243 geniCodeAssign (op, result, 0);
2249 /*-----------------------------------------------------------------*/
2250 /* geniCodePreInc - generate code for preIncrement */
2251 /*-----------------------------------------------------------------*/
2253 geniCodePreInc (operand * op)
2256 sym_link *optype = operandType (op);
2257 operand *rop = (IS_ITEMP (op) ?
2258 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2260 sym_link *roptype = operandType (rop);
2266 werror (E_LVALUE_REQUIRED, "++");
2271 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2272 if (IS_FLOAT (roptype))
2273 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2275 ic = newiCode ('+', rop, operandFromLit (size));
2276 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2280 return geniCodeAssign (op, result, 0);
2283 /*-----------------------------------------------------------------*/
2284 /* geniCodePostDec - generates code for Post decrement */
2285 /*-----------------------------------------------------------------*/
2287 geniCodePostDec (operand * op)
2291 sym_link *optype = operandType (op);
2293 operand *rv = (IS_ITEMP (op) ?
2294 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2296 sym_link *rvtype = operandType (rv);
2299 /* if this is not an address we have trouble */
2302 werror (E_LVALUE_REQUIRED, "--");
2306 rOp = newiTempOperand (rvtype, 0);
2307 OP_SYMBOL(rOp)->noSpilLoc = 1;
2310 OP_SYMBOL(rv)->noSpilLoc = 1;
2312 geniCodeAssign (rOp, rv, 0);
2314 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2315 if (IS_FLOAT (rvtype))
2316 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2318 ic = newiCode ('-', rv, operandFromLit (size));
2320 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2323 geniCodeAssign (op, result, 0);
2329 /*-----------------------------------------------------------------*/
2330 /* geniCodePreDec - generate code for pre decrement */
2331 /*-----------------------------------------------------------------*/
2333 geniCodePreDec (operand * op)
2336 sym_link *optype = operandType (op);
2337 operand *rop = (IS_ITEMP (op) ?
2338 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2340 sym_link *roptype = operandType (rop);
2346 werror (E_LVALUE_REQUIRED, "--");
2351 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2352 if (IS_FLOAT (roptype))
2353 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2355 ic = newiCode ('-', rop, operandFromLit (size));
2356 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2360 return geniCodeAssign (op, result, 0);
2364 /*-----------------------------------------------------------------*/
2365 /* geniCodeBitwise - gen int code for bitWise operators */
2366 /*-----------------------------------------------------------------*/
2368 geniCodeBitwise (operand * left, operand * right,
2369 int oper, sym_link * resType)
2373 left = geniCodeCast (resType, left, TRUE);
2374 right = geniCodeCast (resType, right, TRUE);
2376 ic = newiCode (oper, left, right);
2377 IC_RESULT (ic) = newiTempOperand (resType, 0);
2380 return IC_RESULT (ic);
2383 /*-----------------------------------------------------------------*/
2384 /* geniCodeAddressOf - gens icode for '&' address of operator */
2385 /*-----------------------------------------------------------------*/
2387 geniCodeAddressOf (operand * op)
2391 sym_link *optype = operandType (op);
2392 sym_link *opetype = getSpec (optype);
2394 /* lvalue check already done in decorateType */
2395 /* this must be a lvalue */
2396 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2397 /* werror (E_LVALUE_REQUIRED,"&"); */
2402 p->class = DECLARATOR;
2404 /* set the pointer depending on the storage class */
2405 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2406 DCL_PTR_CONST (p) = port->mem.code_ro;
2408 /* make sure we preserve the const & volatile */
2409 if (IS_CONSTANT (opetype))
2410 DCL_PTR_CONST (p) = 1;
2412 if (IS_VOLATILE (opetype))
2413 DCL_PTR_VOLATILE (p) = 1;
2415 p->next = copyLinkChain (optype);
2417 /* if already a temp */
2420 setOperandType (op, p);
2425 /* other wise make this of the type coming in */
2426 ic = newiCode (ADDRESS_OF, op, NULL);
2427 IC_RESULT (ic) = newiTempOperand (p, 1);
2428 IC_RESULT (ic)->isaddr = 0;
2430 return IC_RESULT (ic);
2432 /*-----------------------------------------------------------------*/
2433 /* setOClass - sets the output class depending on the pointer type */
2434 /*-----------------------------------------------------------------*/
2436 setOClass (sym_link * ptr, sym_link * spec)
2438 switch (DCL_TYPE (ptr))
2441 SPEC_OCLS (spec) = data;
2445 SPEC_OCLS (spec) = generic;
2449 SPEC_OCLS (spec) = xdata;
2453 SPEC_OCLS (spec) = code;
2457 SPEC_OCLS (spec) = idata;
2461 SPEC_OCLS (spec) = xstack;
2465 SPEC_OCLS (spec) = eeprom;
2474 /*-----------------------------------------------------------------*/
2475 /* geniCodeDerefPtr - dereference pointer with '*' */
2476 /*-----------------------------------------------------------------*/
2478 geniCodeDerefPtr (operand * op,int lvl)
2480 sym_link *rtype, *retype;
2481 sym_link *optype = operandType (op);
2483 /* if this is a pointer then generate the rvalue */
2484 if (IS_PTR (optype))
2486 if (IS_TRUE_SYMOP (op))
2489 op = geniCodeRValue (op, TRUE);
2492 op = geniCodeRValue (op, TRUE);
2495 /* now get rid of the pointer part */
2496 if (isLvaluereq(lvl) && IS_ITEMP (op))
2498 retype = getSpec (rtype = copyLinkChain (optype));
2502 retype = getSpec (rtype = copyLinkChain (optype->next));
2505 /* if this is a pointer then outputclass needs 2b updated */
2506 if (IS_PTR (optype))
2507 setOClass (optype, retype);
2509 op->isGptr = IS_GENPTR (optype);
2511 /* if the pointer was declared as a constant */
2512 /* then we cannot allow assignment to the derefed */
2513 if (IS_PTR_CONST (optype))
2514 SPEC_CONST (retype) = 1;
2516 op->isaddr = (IS_PTR (rtype) ||
2517 IS_STRUCT (rtype) ||
2522 if (!isLvaluereq(lvl))
2523 op = geniCodeRValue (op, TRUE);
2525 setOperandType (op, rtype);
2530 /*-----------------------------------------------------------------*/
2531 /* geniCodeUnaryMinus - does a unary minus of the operand */
2532 /*-----------------------------------------------------------------*/
2534 geniCodeUnaryMinus (operand * op)
2537 sym_link *optype = operandType (op);
2539 if (IS_LITERAL (optype))
2540 return operandFromLit (-floatFromVal (op->operand.valOperand));
2542 ic = newiCode (UNARYMINUS, op, NULL);
2543 IC_RESULT (ic) = newiTempOperand (optype, 0);
2545 return IC_RESULT (ic);
2548 /*-----------------------------------------------------------------*/
2549 /* geniCodeLeftShift - gen i code for left shift */
2550 /*-----------------------------------------------------------------*/
2552 geniCodeLeftShift (operand * left, operand * right)
2556 ic = newiCode (LEFT_OP, left, right);
2557 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2559 return IC_RESULT (ic);
2562 /*-----------------------------------------------------------------*/
2563 /* geniCodeRightShift - gen i code for right shift */
2564 /*-----------------------------------------------------------------*/
2566 geniCodeRightShift (operand * left, operand * right)
2570 ic = newiCode (RIGHT_OP, left, right);
2571 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2573 return IC_RESULT (ic);
2576 /*-----------------------------------------------------------------*/
2577 /* geniCodeLogic- logic code */
2578 /*-----------------------------------------------------------------*/
2580 geniCodeLogic (operand * left, operand * right, int op)
2584 sym_link *rtype = operandType (right);
2585 sym_link *ltype = operandType (left);
2587 /* left is integral type and right is literal then
2588 check if the literal value is within bounds */
2589 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2591 checkConstantRange(ltype,
2592 OP_VALUE(right), "compare operation", 1);
2595 ctype = usualBinaryConversions (&left, &right);
2597 ic = newiCode (op, left, right);
2598 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2600 /* if comparing float
2601 and not a '==' || '!=' || '&&' || '||' (these
2603 if (IS_FLOAT(ctype) &&
2611 return IC_RESULT (ic);
2614 /*-----------------------------------------------------------------*/
2615 /* geniCodeUnary - for a a generic unary operation */
2616 /*-----------------------------------------------------------------*/
2618 geniCodeUnary (operand * op, int oper)
2620 iCode *ic = newiCode (oper, op, NULL);
2622 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2624 return IC_RESULT (ic);
2627 /*-----------------------------------------------------------------*/
2628 /* geniCodeConditional - geniCode for '?' ':' operation */
2629 /*-----------------------------------------------------------------*/
2631 geniCodeConditional (ast * tree,int lvl)
2634 symbol *falseLabel = newiTempLabel (NULL);
2635 symbol *exitLabel = newiTempLabel (NULL);
2636 operand *cond = ast2iCode (tree->left,lvl+1);
2637 operand *true, *false, *result;
2639 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2643 true = ast2iCode (tree->right->left,lvl+1);
2645 /* move the value to a new Operand */
2646 result = newiTempOperand (tree->right->ftype, 0);
2647 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2649 /* generate an unconditional goto */
2650 geniCodeGoto (exitLabel);
2652 /* now for the right side */
2653 geniCodeLabel (falseLabel);
2655 false = ast2iCode (tree->right->right,lvl+1);
2656 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2658 /* create the exit label */
2659 geniCodeLabel (exitLabel);
2664 /*-----------------------------------------------------------------*/
2665 /* geniCodeAssign - generate code for assignment */
2666 /*-----------------------------------------------------------------*/
2668 geniCodeAssign (operand * left, operand * right, int nosupdate)
2671 sym_link *ltype = operandType (left);
2672 sym_link *rtype = operandType (right);
2674 if (!left->isaddr && !IS_ITEMP (left))
2676 werror (E_LVALUE_REQUIRED, "assignment");
2680 /* left is integral type and right is literal then
2681 check if the literal value is within bounds */
2682 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2684 checkConstantRange(ltype,
2685 OP_VALUE(right), "= operation", 0);
2688 /* if the left & right type don't exactly match */
2689 /* if pointer set then make sure the check is
2690 done with the type & not the pointer */
2691 /* then cast rights type to left */
2693 /* first check the type for pointer assignement */
2694 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2695 compareType (ltype, rtype) <= 0)
2697 if (compareType (ltype->next, rtype) < 0)
2698 right = geniCodeCast (ltype->next, right, TRUE);
2700 else if (compareType (ltype, rtype) < 0)
2701 right = geniCodeCast (ltype, right, TRUE);
2703 /* if left is a true symbol & ! volatile
2704 create an assignment to temporary for
2705 the right & then assign this temporary
2706 to the symbol this is SSA . isn't it simple
2707 and folks have published mountains of paper on it */
2708 if (IS_TRUE_SYMOP (left) &&
2709 !isOperandVolatile (left, FALSE) &&
2710 isOperandGlobal (left))
2714 if (IS_TRUE_SYMOP (right))
2715 sym = OP_SYMBOL (right);
2716 ic = newiCode ('=', NULL, right);
2717 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2718 SPIL_LOC (right) = sym;
2722 ic = newiCode ('=', NULL, right);
2723 IC_RESULT (ic) = left;
2726 /* if left isgptr flag is set then support
2727 routine will be required */
2731 ic->nosupdate = nosupdate;
2735 /*-----------------------------------------------------------------*/
2736 /* geniCodeSEParms - generate code for side effecting fcalls */
2737 /*-----------------------------------------------------------------*/
2739 geniCodeSEParms (ast * parms,int lvl)
2744 if (parms->type == EX_OP && parms->opval.op == PARAM)
2746 geniCodeSEParms (parms->left,lvl);
2747 geniCodeSEParms (parms->right,lvl);
2751 /* hack don't like this but too lazy to think of
2753 if (IS_ADDRESS_OF_OP (parms))
2754 parms->left->lvalue = 1;
2756 if (IS_CAST_OP (parms) &&
2757 IS_PTR (parms->ftype) &&
2758 IS_ADDRESS_OF_OP (parms->right))
2759 parms->right->left->lvalue = 1;
2761 parms->opval.oprnd =
2762 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2764 parms->type = EX_OPERAND;
2767 /*-----------------------------------------------------------------*/
2768 /* geniCodeParms - generates parameters */
2769 /*-----------------------------------------------------------------*/
2771 geniCodeParms (ast * parms, value *argVals, int *stack,
2772 sym_link * fetype, symbol * func,int lvl)
2780 if (argVals==NULL) {
2782 argVals=FUNC_ARGS(func->type);
2785 /* if this is a param node then do the left & right */
2786 if (parms->type == EX_OP && parms->opval.op == PARAM)
2788 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2789 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2793 /* get the parameter value */
2794 if (parms->type == EX_OPERAND)
2795 pval = parms->opval.oprnd;
2798 /* maybe this else should go away ?? */
2799 /* hack don't like this but too lazy to think of
2801 if (IS_ADDRESS_OF_OP (parms))
2802 parms->left->lvalue = 1;
2804 if (IS_CAST_OP (parms) &&
2805 IS_PTR (parms->ftype) &&
2806 IS_ADDRESS_OF_OP (parms->right))
2807 parms->right->left->lvalue = 1;
2809 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2812 /* if register parm then make it a send */
2813 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2814 IFFUNC_ISBUILTIN(func->type))
2816 ic = newiCode (SEND, pval, NULL);
2817 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2822 /* now decide whether to push or assign */
2823 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2827 operand *top = operandFromSymbol (argVals->sym);
2828 /* clear useDef and other bitVectors */
2829 OP_USES (top) = OP_DEFS (top) = OP_SYMBOL(top)->clashes = NULL;
2830 geniCodeAssign (top, pval, 1);
2834 sym_link *p = operandType (pval);
2836 ic = newiCode (IPUSH, pval, NULL);
2838 /* update the stack adjustment */
2839 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2844 argVals=argVals->next;
2848 /*-----------------------------------------------------------------*/
2849 /* geniCodeCall - generates temp code for calling */
2850 /*-----------------------------------------------------------------*/
2852 geniCodeCall (operand * left, ast * parms,int lvl)
2856 sym_link *type, *etype;
2859 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2860 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2861 werror (E_FUNCTION_EXPECTED);
2865 /* take care of parameters with side-effecting
2866 function calls in them, this is required to take care
2867 of overlaying function parameters */
2868 geniCodeSEParms (parms,lvl);
2870 /* first the parameters */
2871 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2873 /* now call : if symbol then pcall */
2874 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2875 ic = newiCode (PCALL, left, NULL);
2877 ic = newiCode (CALL, left, NULL);
2879 type = copyLinkChain (operandType (left)->next);
2880 etype = getSpec (type);
2881 SPEC_EXTR (etype) = 0;
2882 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2886 /* stack adjustment after call */
2887 ic->parmBytes = stack;
2892 /*-----------------------------------------------------------------*/
2893 /* geniCodeReceive - generate intermediate code for "receive" */
2894 /*-----------------------------------------------------------------*/
2896 geniCodeReceive (value * args)
2898 /* for all arguments that are passed in registers */
2902 if (IS_REGPARM (args->etype))
2904 operand *opr = operandFromValue (args);
2906 symbol *sym = OP_SYMBOL (opr);
2909 /* we will use it after all optimizations
2910 and before liveRange calculation */
2911 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2914 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2915 options.stackAuto == 0 &&
2916 /* !TARGET_IS_DS390) */
2917 (!(options.model == MODEL_FLAT24)) )
2922 opl = newiTempOperand (args->type, 0);
2924 sym->reqv->key = sym->key;
2925 OP_SYMBOL (sym->reqv)->key = sym->key;
2926 OP_SYMBOL (sym->reqv)->isreqv = 1;
2927 OP_SYMBOL (sym->reqv)->islocal = 0;
2928 SPIL_LOC (sym->reqv) = sym;
2932 ic = newiCode (RECEIVE, NULL, NULL);
2933 currFunc->recvSize = getSize (sym->etype);
2934 IC_RESULT (ic) = opr;
2942 /*-----------------------------------------------------------------*/
2943 /* geniCodeFunctionBody - create the function body */
2944 /*-----------------------------------------------------------------*/
2946 geniCodeFunctionBody (ast * tree,int lvl)
2953 /* reset the auto generation */
2959 func = ast2iCode (tree->left,lvl+1);
2960 fetype = getSpec (operandType (func));
2962 savelineno = lineno;
2963 lineno = OP_SYMBOL (func)->lineDef;
2964 /* create an entry label */
2965 geniCodeLabel (entryLabel);
2966 lineno = savelineno;
2968 /* create a proc icode */
2969 ic = newiCode (FUNCTION, func, NULL);
2970 ic->lineno = OP_SYMBOL (func)->lineDef;
2974 /* for all parameters that are passed
2975 on registers add a "receive" */
2976 geniCodeReceive (tree->values.args);
2978 /* generate code for the body */
2979 ast2iCode (tree->right,lvl+1);
2981 /* create a label for return */
2982 geniCodeLabel (returnLabel);
2984 /* now generate the end proc */
2985 ic = newiCode (ENDFUNCTION, func, NULL);
2990 /*-----------------------------------------------------------------*/
2991 /* geniCodeReturn - gen icode for 'return' statement */
2992 /*-----------------------------------------------------------------*/
2994 geniCodeReturn (operand * op)
2998 /* if the operand is present force an rvalue */
3000 op = geniCodeRValue (op, FALSE);
3002 ic = newiCode (RETURN, op, NULL);
3006 /*-----------------------------------------------------------------*/
3007 /* geniCodeIfx - generates code for extended if statement */
3008 /*-----------------------------------------------------------------*/
3010 geniCodeIfx (ast * tree,int lvl)
3013 operand *condition = ast2iCode (tree->left,lvl+1);
3016 /* if condition is null then exit */
3020 condition = geniCodeRValue (condition, FALSE);
3022 cetype = getSpec (operandType (condition));
3023 /* if the condition is a literal */
3024 if (IS_LITERAL (cetype))
3026 if (floatFromVal (condition->operand.valOperand))
3028 if (tree->trueLabel)
3029 geniCodeGoto (tree->trueLabel);
3035 if (tree->falseLabel)
3036 geniCodeGoto (tree->falseLabel);
3043 if (tree->trueLabel)
3045 ic = newiCodeCondition (condition,
3050 if (tree->falseLabel)
3051 geniCodeGoto (tree->falseLabel);
3055 ic = newiCodeCondition (condition,
3062 ast2iCode (tree->right,lvl+1);
3065 /*-----------------------------------------------------------------*/
3066 /* geniCodeJumpTable - tries to create a jump table for switch */
3067 /*-----------------------------------------------------------------*/
3069 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3071 int min = 0, max = 0, t, cnt = 0;
3078 if (!tree || !caseVals)
3081 /* the criteria for creating a jump table is */
3082 /* all integer numbers between the maximum & minimum must */
3083 /* be present , the maximum value should not exceed 255 */
3084 min = max = (int) floatFromVal (vch = caseVals);
3085 sprintf (buffer, "_case_%d_%d",
3086 tree->values.switchVals.swNum,
3088 addSet (&labels, newiTempLabel (buffer));
3090 /* if there is only one case value then no need */
3091 if (!(vch = vch->next))
3096 if (((t = (int) floatFromVal (vch)) - max) != 1)
3098 sprintf (buffer, "_case_%d_%d",
3099 tree->values.switchVals.swNum,
3101 addSet (&labels, newiTempLabel (buffer));
3107 /* if the number of case statements <= 2 then */
3108 /* it is not economical to create the jump table */
3109 /* since two compares are needed for boundary conditions */
3110 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3113 if (tree->values.switchVals.swDefault)
3114 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3116 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3118 falseLabel = newiTempLabel (buffer);
3120 /* so we can create a jumptable */
3121 /* first we rule out the boundary conditions */
3122 /* if only optimization says so */
3123 if (!optimize.noJTabBoundary)
3125 sym_link *cetype = getSpec (operandType (cond));
3126 /* no need to check the lower bound if
3127 the condition is unsigned & minimum value is zero */
3128 if (!(min == 0 && SPEC_USIGN (cetype)))
3130 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3131 ic = newiCodeCondition (boundary, falseLabel, NULL);
3135 /* now for upper bounds */
3136 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3137 ic = newiCodeCondition (boundary, falseLabel, NULL);
3141 /* if the min is not zero then we no make it zero */
3144 cond = geniCodeSubtract (cond, operandFromLit (min));
3145 setOperandType (cond, UCHARTYPE);
3148 /* now create the jumptable */
3149 ic = newiCode (JUMPTABLE, NULL, NULL);
3150 IC_JTCOND (ic) = cond;
3151 IC_JTLABELS (ic) = labels;
3156 /*-----------------------------------------------------------------*/
3157 /* geniCodeSwitch - changes a switch to a if statement */
3158 /*-----------------------------------------------------------------*/
3160 geniCodeSwitch (ast * tree,int lvl)
3163 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3164 value *caseVals = tree->values.switchVals.swVals;
3165 symbol *trueLabel, *falseLabel;
3167 /* if we can make this a jump table */
3168 if (geniCodeJumpTable (cond, caseVals, tree))
3169 goto jumpTable; /* no need for the comparison */
3171 /* for the cases defined do */
3175 operand *compare = geniCodeLogic (cond,
3176 operandFromValue (caseVals),
3179 sprintf (buffer, "_case_%d_%d",
3180 tree->values.switchVals.swNum,
3181 (int) floatFromVal (caseVals));
3182 trueLabel = newiTempLabel (buffer);
3184 ic = newiCodeCondition (compare, trueLabel, NULL);
3186 caseVals = caseVals->next;
3191 /* if default is present then goto break else break */
3192 if (tree->values.switchVals.swDefault)
3193 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3195 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3197 falseLabel = newiTempLabel (buffer);
3198 geniCodeGoto (falseLabel);
3201 ast2iCode (tree->right,lvl+1);
3204 /*-----------------------------------------------------------------*/
3205 /* geniCodeInline - intermediate code for inline assembler */
3206 /*-----------------------------------------------------------------*/
3208 geniCodeInline (ast * tree)
3212 ic = newiCode (INLINEASM, NULL, NULL);
3213 IC_INLINE (ic) = tree->values.inlineasm;
3217 /*-----------------------------------------------------------------*/
3218 /* geniCodeArrayInit - intermediate code for array initializer */
3219 /*-----------------------------------------------------------------*/
3221 geniCodeArrayInit (ast * tree, operand *array)
3225 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3226 ic = newiCode (ARRAYINIT, array, NULL);
3227 IC_ARRAYILIST (ic) = tree->values.constlist;
3229 operand *left=newOperand(), *right=newOperand();
3230 left->type=right->type=SYMBOL;
3231 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3232 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3233 ic = newiCode (ARRAYINIT, left, right);
3238 /*-----------------------------------------------------------------*/
3239 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3240 /* particular case. Ie : assigning or dereferencing array or ptr */
3241 /*-----------------------------------------------------------------*/
3242 set * lvaluereqSet = NULL;
3243 typedef struct lvalItem
3250 /*-----------------------------------------------------------------*/
3251 /* addLvaluereq - add a flag for lvalreq for current ast level */
3252 /*-----------------------------------------------------------------*/
3253 void addLvaluereq(int lvl)
3255 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3258 addSetHead(&lvaluereqSet,lpItem);
3261 /*-----------------------------------------------------------------*/
3262 /* delLvaluereq - del a flag for lvalreq for current ast level */
3263 /*-----------------------------------------------------------------*/
3267 lpItem = getSet(&lvaluereqSet);
3268 if(lpItem) Safe_free(lpItem);
3270 /*-----------------------------------------------------------------*/
3271 /* clearLvaluereq - clear lvalreq flag */
3272 /*-----------------------------------------------------------------*/
3273 void clearLvaluereq()
3276 lpItem = peekSet(lvaluereqSet);
3277 if(lpItem) lpItem->req = 0;
3279 /*-----------------------------------------------------------------*/
3280 /* getLvaluereq - get the last lvalreq level */
3281 /*-----------------------------------------------------------------*/
3282 int getLvaluereqLvl()
3285 lpItem = peekSet(lvaluereqSet);
3286 if(lpItem) return lpItem->lvl;
3289 /*-----------------------------------------------------------------*/
3290 /* isLvaluereq - is lvalreq valid for this level ? */
3291 /*-----------------------------------------------------------------*/
3292 int isLvaluereq(int lvl)
3295 lpItem = peekSet(lvaluereqSet);
3296 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3300 /*-----------------------------------------------------------------*/
3301 /* ast2iCode - creates an icodeList from an ast */
3302 /*-----------------------------------------------------------------*/
3304 ast2iCode (ast * tree,int lvl)
3306 operand *left = NULL;
3307 operand *right = NULL;
3310 /* set the global variables for filename & line number */
3312 filename = tree->filename;
3314 lineno = tree->lineno;
3316 block = tree->block;
3318 scopeLevel = tree->level;
3320 if (tree->type == EX_VALUE)
3321 return operandFromValue (tree->opval.val);
3323 if (tree->type == EX_LINK)
3324 return operandFromLink (tree->opval.lnk);
3326 /* if we find a nullop */
3327 if (tree->type == EX_OP &&
3328 (tree->opval.op == NULLOP ||
3329 tree->opval.op == BLOCK))
3331 ast2iCode (tree->left,lvl+1);
3332 ast2iCode (tree->right,lvl+1);
3336 /* special cases for not evaluating */
3337 if (tree->opval.op != ':' &&
3338 tree->opval.op != '?' &&
3339 tree->opval.op != CALL &&
3340 tree->opval.op != IFX &&
3341 tree->opval.op != LABEL &&
3342 tree->opval.op != GOTO &&
3343 tree->opval.op != SWITCH &&
3344 tree->opval.op != FUNCTION &&
3345 tree->opval.op != INLINEASM)
3348 if (IS_ASSIGN_OP (tree->opval.op) ||
3349 IS_DEREF_OP (tree) ||
3350 (tree->opval.op == '&' && !tree->right) ||
3351 tree->opval.op == PTR_OP)
3354 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3355 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3358 left = operandFromAst (tree->left,lvl);
3360 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3361 left = geniCodeRValue (left, TRUE);
3365 left = operandFromAst (tree->left,lvl);
3367 if (tree->opval.op == INC_OP ||
3368 tree->opval.op == DEC_OP)
3371 right = operandFromAst (tree->right,lvl);
3376 right = operandFromAst (tree->right,lvl);
3380 /* now depending on the type of operand */
3381 /* this will be a biggy */
3382 switch (tree->opval.op)
3385 case '[': /* array operation */
3387 //sym_link *ltype = operandType (left);
3388 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3389 left = geniCodeRValue (left, FALSE);
3390 right = geniCodeRValue (right, TRUE);
3393 return geniCodeArray (left, right,lvl);
3395 case '.': /* structure dereference */
3396 if (IS_PTR (operandType (left)))
3397 left = geniCodeRValue (left, TRUE);
3399 left = geniCodeRValue (left, FALSE);
3401 return geniCodeStruct (left, right, tree->lvalue);
3403 case PTR_OP: /* structure pointer dereference */
3406 pType = operandType (left);
3407 left = geniCodeRValue (left, TRUE);
3409 setOClass (pType, getSpec (operandType (left)));
3412 return geniCodeStruct (left, right, tree->lvalue);
3414 case INC_OP: /* increment operator */
3416 return geniCodePostInc (left);
3418 return geniCodePreInc (right);
3420 case DEC_OP: /* decrement operator */
3422 return geniCodePostDec (left);
3424 return geniCodePreDec (right);
3426 case '&': /* bitwise and or address of operator */
3428 { /* this is a bitwise operator */
3429 left = geniCodeRValue (left, FALSE);
3430 right = geniCodeRValue (right, FALSE);
3431 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3434 return geniCodeAddressOf (left);
3436 case '|': /* bitwise or & xor */
3438 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3439 geniCodeRValue (right, FALSE),
3444 return geniCodeDivision (geniCodeRValue (left, FALSE),
3445 geniCodeRValue (right, FALSE));
3448 return geniCodeModulus (geniCodeRValue (left, FALSE),
3449 geniCodeRValue (right, FALSE));
3452 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3453 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3455 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3459 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3460 geniCodeRValue (right, FALSE));
3462 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3466 return geniCodeAdd (geniCodeRValue (left, FALSE),
3467 geniCodeRValue (right, FALSE),lvl);
3469 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3472 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3473 geniCodeRValue (right, FALSE));
3476 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3477 geniCodeRValue (right, FALSE));
3479 return geniCodeCast (operandType (left),
3480 geniCodeRValue (right, FALSE), FALSE);
3486 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3490 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3491 setOperandType (op, UCHARTYPE);
3502 return geniCodeLogic (geniCodeRValue (left, FALSE),
3503 geniCodeRValue (right, FALSE),
3506 return geniCodeConditional (tree,lvl);
3509 return operandFromLit (getSize (tree->right->ftype));
3513 sym_link *rtype = operandType (right);
3514 sym_link *ltype = operandType (left);
3515 if (IS_PTR (rtype) && IS_ITEMP (right)
3516 && right->isaddr && compareType (rtype->next, ltype) == 1)
3517 right = geniCodeRValue (right, TRUE);
3519 right = geniCodeRValue (right, FALSE);
3521 geniCodeAssign (left, right, 0);
3526 geniCodeAssign (left,
3527 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3529 geniCodeRValue (right, FALSE),FALSE), 0);
3533 geniCodeAssign (left,
3534 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3536 geniCodeRValue (right, FALSE)), 0);
3539 geniCodeAssign (left,
3540 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3542 geniCodeRValue (right, FALSE)), 0);
3545 sym_link *rtype = operandType (right);
3546 sym_link *ltype = operandType (left);
3547 if (IS_PTR (rtype) && IS_ITEMP (right)
3548 && right->isaddr && compareType (rtype->next, ltype) == 1)
3549 right = geniCodeRValue (right, TRUE);
3551 right = geniCodeRValue (right, FALSE);
3554 return geniCodeAssign (left,
3555 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3561 sym_link *rtype = operandType (right);
3562 sym_link *ltype = operandType (left);
3563 if (IS_PTR (rtype) && IS_ITEMP (right)
3564 && right->isaddr && compareType (rtype->next, ltype) == 1)
3566 right = geniCodeRValue (right, TRUE);
3570 right = geniCodeRValue (right, FALSE);
3573 geniCodeAssign (left,
3574 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3580 geniCodeAssign (left,
3581 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3583 geniCodeRValue (right, FALSE)), 0);
3586 geniCodeAssign (left,
3587 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3589 geniCodeRValue (right, FALSE)), 0);
3592 geniCodeAssign (left,
3593 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3595 geniCodeRValue (right, FALSE),
3597 operandType (left)), 0);
3600 geniCodeAssign (left,
3601 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3603 geniCodeRValue (right, FALSE),
3605 operandType (left)), 0);
3608 geniCodeAssign (left,
3609 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3611 geniCodeRValue (right, FALSE),
3613 operandType (left)), 0);
3615 return geniCodeRValue (right, FALSE);
3618 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3621 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3622 return ast2iCode (tree->right,lvl+1);
3625 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3626 return ast2iCode (tree->right,lvl+1);
3629 geniCodeFunctionBody (tree,lvl);
3633 geniCodeReturn (right);
3637 geniCodeIfx (tree,lvl);
3641 geniCodeSwitch (tree,lvl);
3645 geniCodeInline (tree);
3649 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3656 /*-----------------------------------------------------------------*/
3657 /* reverseICChain - gets from the list and creates a linkedlist */
3658 /*-----------------------------------------------------------------*/
3665 while ((loop = getSet (&iCodeChain)))
3677 /*-----------------------------------------------------------------*/
3678 /* iCodeFromAst - given an ast will convert it to iCode */
3679 /*-----------------------------------------------------------------*/
3681 iCodeFromAst (ast * tree)
3683 returnLabel = newiTempLabel ("_return");
3684 entryLabel = newiTempLabel ("_entry");
3686 return reverseiCChain ();