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, int implicit)
1587 sym_link *rtype = operandType (*op2);
1588 sym_link *ltype = operandType (*op1);
1590 ctype = computeType (ltype, rtype);
1591 *op1 = geniCodeCast (ctype, *op1, implicit);
1592 *op2 = geniCodeCast (ctype, *op2, implicit);
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 // !implicit is always ok, e.g. "(char *) = (char *) + 3;"
1691 !(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1692 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1693 // no way to set the storage
1694 if (IS_LITERAL(optype)) {
1695 werror(E_LITERAL_GENERIC);
1698 werror(E_NONPTR2_GENPTR);
1702 werror(W_INTEGRAL2PTR_NOCAST);
1707 // shouldn't do that with float, array or structure unless to void
1708 if (!IS_VOID(getSpec(type)) &&
1709 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1710 werror(E_INCOMPAT_TYPES);
1714 } else { // from a pointer to a pointer
1715 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1716 // if not a pointer to a function
1717 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1718 if (implicit) { // if not to generic, they have to match
1719 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1720 werror(E_INCOMPAT_PTYPES);
1727 } else { // to a non pointer
1728 if (IS_PTR(optype)) { // from a pointer
1729 if (implicit) { // sneaky
1730 if (IS_INTEGRAL(type)) {
1731 werror(W_PTR2INTEGRAL_NOCAST);
1733 } else { // shouldn't do that with float, array or structure
1734 werror(E_INCOMPAT_TYPES);
1741 printFromToType (optype, type);
1744 /* if they are the same size create an assignment */
1745 if (getSize (type) == getSize (optype) &&
1746 !IS_BITFIELD (type) &&
1748 !IS_FLOAT (optype) &&
1749 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1750 (!IS_SPEC (type) && !IS_SPEC (optype))))
1753 ic = newiCode ('=', NULL, op);
1754 IC_RESULT (ic) = newiTempOperand (type, 0);
1755 SPIL_LOC (IC_RESULT (ic)) =
1756 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1757 IC_RESULT (ic)->isaddr = 0;
1761 ic = newiCode (CAST, operandFromLink (type),
1762 geniCodeRValue (op, FALSE));
1764 IC_RESULT (ic) = newiTempOperand (type, 0);
1767 /* preserve the storage class & output class */
1768 /* of the original variable */
1769 restype = getSpec (operandType (IC_RESULT (ic)));
1770 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1771 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1774 return IC_RESULT (ic);
1777 /*-----------------------------------------------------------------*/
1778 /* geniCodeLabel - will create a Label */
1779 /*-----------------------------------------------------------------*/
1781 geniCodeLabel (symbol * label)
1785 ic = newiCodeLabelGoto (LABEL, label);
1789 /*-----------------------------------------------------------------*/
1790 /* geniCodeGoto - will create a Goto */
1791 /*-----------------------------------------------------------------*/
1793 geniCodeGoto (symbol * label)
1797 ic = newiCodeLabelGoto (GOTO, label);
1801 /*-----------------------------------------------------------------*/
1802 /* geniCodeMultiply - gen intermediate code for multiplication */
1803 /*-----------------------------------------------------------------*/
1805 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1812 /* if they are both literal then we know the result */
1813 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1814 return operandFromValue (valMult (left->operand.valOperand,
1815 right->operand.valOperand));
1817 if (IS_LITERAL(retype)) {
1818 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1821 resType = usualBinaryConversions (&left, &right, TRUE);
1823 rtype = operandType (right);
1824 retype = getSpec (rtype);
1825 ltype = operandType (left);
1826 letype = getSpec (ltype);
1830 SPEC_NOUN(getSpec(resType))=V_INT;
1833 /* if the right is a literal & power of 2 */
1834 /* then make it a left shift */
1835 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1836 efficient in most cases than 2 bytes result = 2 bytes << literal
1837 if port has 1 byte muldiv */
1838 if (p2 && !IS_FLOAT (letype) &&
1839 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1840 (port->support.muldiv == 1)))
1842 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1844 /* LEFT_OP need same size for left and result, */
1845 left = geniCodeCast (resType, left, TRUE);
1846 ltype = operandType (left);
1848 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1852 ic = newiCode ('*', left, right); /* normal multiplication */
1853 /* if the size left or right > 1 then support routine */
1854 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1858 IC_RESULT (ic) = newiTempOperand (resType, 1);
1861 return IC_RESULT (ic);
1864 /*-----------------------------------------------------------------*/
1865 /* geniCodeDivision - gen intermediate code for division */
1866 /*-----------------------------------------------------------------*/
1868 geniCodeDivision (operand * left, operand * right)
1873 sym_link *rtype = operandType (right);
1874 sym_link *retype = getSpec (rtype);
1875 sym_link *ltype = operandType (left);
1876 sym_link *letype = getSpec (ltype);
1878 resType = usualBinaryConversions (&left, &right, TRUE);
1880 /* if the right is a literal & power of 2 */
1881 /* then make it a right shift */
1882 if (IS_LITERAL (retype) &&
1883 !IS_FLOAT (letype) &&
1884 (p2 = powof2 ((unsigned long)
1885 floatFromVal (right->operand.valOperand)))) {
1886 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1890 ic = newiCode ('/', left, right); /* normal division */
1891 /* if the size left or right > 1 then support routine */
1892 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1895 IC_RESULT (ic) = newiTempOperand (resType, 0);
1898 return IC_RESULT (ic);
1900 /*-----------------------------------------------------------------*/
1901 /* geniCodeModulus - gen intermediate code for modulus */
1902 /*-----------------------------------------------------------------*/
1904 geniCodeModulus (operand * left, operand * right)
1910 /* if they are both literal then we know the result */
1911 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1912 return operandFromValue (valMod (left->operand.valOperand,
1913 right->operand.valOperand));
1915 resType = usualBinaryConversions (&left, &right, TRUE);
1917 /* now they are the same size */
1918 ic = newiCode ('%', left, right);
1920 /* if the size left or right > 1 then support routine */
1921 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1923 IC_RESULT (ic) = newiTempOperand (resType, 0);
1926 return IC_RESULT (ic);
1929 /*-----------------------------------------------------------------*/
1930 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1931 /*-----------------------------------------------------------------*/
1933 geniCodePtrPtrSubtract (operand * left, operand * right)
1939 /* if they are both literals then */
1940 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1942 result = operandFromValue (valMinus (left->operand.valOperand,
1943 right->operand.valOperand));
1947 ic = newiCode ('-', left, right);
1949 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1953 return geniCodeDivision (result,
1954 operandFromLit (getSize (ltype->next)));
1957 /*-----------------------------------------------------------------*/
1958 /* geniCodeSubtract - generates code for subtraction */
1959 /*-----------------------------------------------------------------*/
1961 geniCodeSubtract (operand * left, operand * right)
1968 /* if they both pointers then */
1969 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1970 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1971 return geniCodePtrPtrSubtract (left, right);
1973 /* if they are both literal then we know the result */
1974 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1975 && left->isLiteral && right->isLiteral)
1976 return operandFromValue (valMinus (left->operand.valOperand,
1977 right->operand.valOperand));
1979 /* if left is an array or pointer */
1980 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1982 isarray = left->isaddr;
1983 right = geniCodeMultiply (right,
1984 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1985 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1988 { /* make them the same size */
1989 resType = usualBinaryConversions (&left, &right, TRUE);
1992 ic = newiCode ('-', left, right);
1994 IC_RESULT (ic) = newiTempOperand (resType, 1);
1995 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1997 /* if left or right is a float */
1998 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2002 return IC_RESULT (ic);
2005 /*-----------------------------------------------------------------*/
2006 /* geniCodeAdd - generates iCode for addition */
2007 /*-----------------------------------------------------------------*/
2009 geniCodeAdd (operand * left, operand * right, int lvl, int ptrMath)
2017 /* if left is an array then array access */
2018 if (IS_ARRAY (ltype))
2019 return geniCodeArray (left, right,lvl);
2021 /* if the right side is LITERAL zero */
2022 /* return the left side */
2023 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2026 /* if left is literal zero return right */
2027 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2030 /* if left is an array or pointer then size */
2031 if (ptrMath && IS_PTR (ltype))
2033 isarray = left->isaddr;
2034 // there is no need to multiply with 1
2035 if (getSize(ltype->next)!=1) {
2036 size = operandFromLit (getSize (ltype->next));
2037 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2039 resType = copyLinkChain (ltype);
2042 { // make them the same size
2043 resType = usualBinaryConversions (&left, &right, FALSE);
2046 /* if they are both literals then we know */
2047 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2048 && left->isLiteral && right->isLiteral)
2049 return operandFromValue (valPlus (valFromType (letype),
2050 valFromType (retype)));
2052 ic = newiCode ('+', left, right);
2054 IC_RESULT (ic) = newiTempOperand (resType, 1);
2055 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2057 /* if left or right is a float then support
2059 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2064 return IC_RESULT (ic);
2068 /*-----------------------------------------------------------------*/
2069 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2070 /*-----------------------------------------------------------------*/
2072 aggrToPtr (sym_link * type, bool force)
2078 if (IS_PTR (type) && !force)
2081 etype = getSpec (type);
2085 /* if the output class is generic */
2086 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2087 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2089 /* if the variable was declared a constant */
2090 /* then the pointer points to a constant */
2091 if (IS_CONSTANT (etype))
2092 DCL_PTR_CONST (ptype) = 1;
2094 /* the variable was volatile then pointer to volatile */
2095 if (IS_VOLATILE (etype))
2096 DCL_PTR_VOLATILE (ptype) = 1;
2100 /*-----------------------------------------------------------------*/
2101 /* geniCodeArray2Ptr - array to pointer */
2102 /*-----------------------------------------------------------------*/
2104 geniCodeArray2Ptr (operand * op)
2106 sym_link *optype = operandType (op);
2107 sym_link *opetype = getSpec (optype);
2109 /* set the pointer depending on the storage class */
2110 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2111 DCL_PTR_CONST (optype) = port->mem.code_ro;
2114 /* if the variable was declared a constant */
2115 /* then the pointer points to a constant */
2116 if (IS_CONSTANT (opetype))
2117 DCL_PTR_CONST (optype) = 1;
2119 /* the variable was volatile then pointer to volatile */
2120 if (IS_VOLATILE (opetype))
2121 DCL_PTR_VOLATILE (optype) = 1;
2127 /*-----------------------------------------------------------------*/
2128 /* geniCodeArray - array access */
2129 /*-----------------------------------------------------------------*/
2131 geniCodeArray (operand * left, operand * right,int lvl)
2134 sym_link *ltype = operandType (left);
2138 if (IS_PTR (ltype->next) && left->isaddr)
2140 left = geniCodeRValue (left, FALSE);
2142 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl, 1), lvl);
2145 right = geniCodeMultiply (right,
2146 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2148 /* we can check for limits here */
2149 if (isOperandLiteral (right) &&
2152 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2154 werror (E_ARRAY_BOUND);
2155 right = operandFromLit (0);
2158 ic = newiCode ('+', left, right);
2160 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2161 !IS_AGGREGATE (ltype->next) &&
2162 !IS_PTR (ltype->next))
2163 ? ltype : ltype->next), 0);
2165 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2167 return IC_RESULT (ic);
2170 /*-----------------------------------------------------------------*/
2171 /* geniCodeStruct - generates intermediate code for structres */
2172 /*-----------------------------------------------------------------*/
2174 geniCodeStruct (operand * left, operand * right, bool islval)
2177 sym_link *type = operandType (left);
2178 sym_link *etype = getSpec (type);
2180 symbol *element = getStructElement (SPEC_STRUCT (etype),
2181 right->operand.symOperand);
2183 /* add the offset */
2184 ic = newiCode ('+', left, operandFromLit (element->offset));
2186 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2188 /* preserve the storage & output class of the struct */
2189 /* as well as the volatile attribute */
2190 retype = getSpec (operandType (IC_RESULT (ic)));
2191 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2192 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2193 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2195 if (IS_PTR (element->type))
2196 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2198 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2202 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2205 /*-----------------------------------------------------------------*/
2206 /* geniCodePostInc - generate int code for Post increment */
2207 /*-----------------------------------------------------------------*/
2209 geniCodePostInc (operand * op)
2213 sym_link *optype = operandType (op);
2215 operand *rv = (IS_ITEMP (op) ?
2216 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2218 sym_link *rvtype = operandType (rv);
2221 /* if this is not an address we have trouble */
2224 werror (E_LVALUE_REQUIRED, "++");
2228 rOp = newiTempOperand (rvtype, 0);
2229 OP_SYMBOL(rOp)->noSpilLoc = 1;
2232 OP_SYMBOL(rv)->noSpilLoc = 1;
2234 geniCodeAssign (rOp, rv, 0);
2236 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2237 if (IS_FLOAT (rvtype))
2238 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2240 ic = newiCode ('+', rv, operandFromLit (size));
2242 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2245 geniCodeAssign (op, result, 0);
2251 /*-----------------------------------------------------------------*/
2252 /* geniCodePreInc - generate code for preIncrement */
2253 /*-----------------------------------------------------------------*/
2255 geniCodePreInc (operand * op)
2258 sym_link *optype = operandType (op);
2259 operand *rop = (IS_ITEMP (op) ?
2260 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2262 sym_link *roptype = operandType (rop);
2268 werror (E_LVALUE_REQUIRED, "++");
2273 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2274 if (IS_FLOAT (roptype))
2275 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2277 ic = newiCode ('+', rop, operandFromLit (size));
2278 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2282 return geniCodeAssign (op, result, 0);
2285 /*-----------------------------------------------------------------*/
2286 /* geniCodePostDec - generates code for Post decrement */
2287 /*-----------------------------------------------------------------*/
2289 geniCodePostDec (operand * op)
2293 sym_link *optype = operandType (op);
2295 operand *rv = (IS_ITEMP (op) ?
2296 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2298 sym_link *rvtype = operandType (rv);
2301 /* if this is not an address we have trouble */
2304 werror (E_LVALUE_REQUIRED, "--");
2308 rOp = newiTempOperand (rvtype, 0);
2309 OP_SYMBOL(rOp)->noSpilLoc = 1;
2312 OP_SYMBOL(rv)->noSpilLoc = 1;
2314 geniCodeAssign (rOp, rv, 0);
2316 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2317 if (IS_FLOAT (rvtype))
2318 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2320 ic = newiCode ('-', rv, operandFromLit (size));
2322 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2325 geniCodeAssign (op, result, 0);
2331 /*-----------------------------------------------------------------*/
2332 /* geniCodePreDec - generate code for pre decrement */
2333 /*-----------------------------------------------------------------*/
2335 geniCodePreDec (operand * op)
2338 sym_link *optype = operandType (op);
2339 operand *rop = (IS_ITEMP (op) ?
2340 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2342 sym_link *roptype = operandType (rop);
2348 werror (E_LVALUE_REQUIRED, "--");
2353 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2354 if (IS_FLOAT (roptype))
2355 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2357 ic = newiCode ('-', rop, operandFromLit (size));
2358 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2362 return geniCodeAssign (op, result, 0);
2366 /*-----------------------------------------------------------------*/
2367 /* geniCodeBitwise - gen int code for bitWise operators */
2368 /*-----------------------------------------------------------------*/
2370 geniCodeBitwise (operand * left, operand * right,
2371 int oper, sym_link * resType)
2375 left = geniCodeCast (resType, left, TRUE);
2376 right = geniCodeCast (resType, right, TRUE);
2378 ic = newiCode (oper, left, right);
2379 IC_RESULT (ic) = newiTempOperand (resType, 0);
2382 return IC_RESULT (ic);
2385 /*-----------------------------------------------------------------*/
2386 /* geniCodeAddressOf - gens icode for '&' address of operator */
2387 /*-----------------------------------------------------------------*/
2389 geniCodeAddressOf (operand * op)
2393 sym_link *optype = operandType (op);
2394 sym_link *opetype = getSpec (optype);
2396 /* lvalue check already done in decorateType */
2397 /* this must be a lvalue */
2398 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2399 /* werror (E_LVALUE_REQUIRED,"&"); */
2404 p->class = DECLARATOR;
2406 /* set the pointer depending on the storage class */
2407 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2408 DCL_PTR_CONST (p) = port->mem.code_ro;
2410 /* make sure we preserve the const & volatile */
2411 if (IS_CONSTANT (opetype))
2412 DCL_PTR_CONST (p) = 1;
2414 if (IS_VOLATILE (opetype))
2415 DCL_PTR_VOLATILE (p) = 1;
2417 p->next = copyLinkChain (optype);
2419 /* if already a temp */
2422 setOperandType (op, p);
2427 /* other wise make this of the type coming in */
2428 ic = newiCode (ADDRESS_OF, op, NULL);
2429 IC_RESULT (ic) = newiTempOperand (p, 1);
2430 IC_RESULT (ic)->isaddr = 0;
2432 return IC_RESULT (ic);
2434 /*-----------------------------------------------------------------*/
2435 /* setOClass - sets the output class depending on the pointer type */
2436 /*-----------------------------------------------------------------*/
2438 setOClass (sym_link * ptr, sym_link * spec)
2440 switch (DCL_TYPE (ptr))
2443 SPEC_OCLS (spec) = data;
2447 SPEC_OCLS (spec) = generic;
2451 SPEC_OCLS (spec) = xdata;
2455 SPEC_OCLS (spec) = code;
2459 SPEC_OCLS (spec) = idata;
2463 SPEC_OCLS (spec) = xstack;
2467 SPEC_OCLS (spec) = eeprom;
2476 /*-----------------------------------------------------------------*/
2477 /* geniCodeDerefPtr - dereference pointer with '*' */
2478 /*-----------------------------------------------------------------*/
2480 geniCodeDerefPtr (operand * op,int lvl)
2482 sym_link *rtype, *retype;
2483 sym_link *optype = operandType (op);
2485 /* if this is a pointer then generate the rvalue */
2486 if (IS_PTR (optype))
2488 if (IS_TRUE_SYMOP (op))
2491 op = geniCodeRValue (op, TRUE);
2494 op = geniCodeRValue (op, TRUE);
2497 /* now get rid of the pointer part */
2498 if (isLvaluereq(lvl) && IS_ITEMP (op))
2500 retype = getSpec (rtype = copyLinkChain (optype));
2504 retype = getSpec (rtype = copyLinkChain (optype->next));
2507 /* if this is a pointer then outputclass needs 2b updated */
2508 if (IS_PTR (optype))
2509 setOClass (optype, retype);
2511 op->isGptr = IS_GENPTR (optype);
2513 /* if the pointer was declared as a constant */
2514 /* then we cannot allow assignment to the derefed */
2515 if (IS_PTR_CONST (optype))
2516 SPEC_CONST (retype) = 1;
2518 op->isaddr = (IS_PTR (rtype) ||
2519 IS_STRUCT (rtype) ||
2524 if (!isLvaluereq(lvl))
2525 op = geniCodeRValue (op, TRUE);
2527 setOperandType (op, rtype);
2532 /*-----------------------------------------------------------------*/
2533 /* geniCodeUnaryMinus - does a unary minus of the operand */
2534 /*-----------------------------------------------------------------*/
2536 geniCodeUnaryMinus (operand * op)
2539 sym_link *optype = operandType (op);
2541 if (IS_LITERAL (optype))
2542 return operandFromLit (-floatFromVal (op->operand.valOperand));
2544 ic = newiCode (UNARYMINUS, op, NULL);
2545 IC_RESULT (ic) = newiTempOperand (optype, 0);
2547 return IC_RESULT (ic);
2550 /*-----------------------------------------------------------------*/
2551 /* geniCodeLeftShift - gen i code for left shift */
2552 /*-----------------------------------------------------------------*/
2554 geniCodeLeftShift (operand * left, operand * right)
2558 ic = newiCode (LEFT_OP, left, right);
2559 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2561 return IC_RESULT (ic);
2564 /*-----------------------------------------------------------------*/
2565 /* geniCodeRightShift - gen i code for right shift */
2566 /*-----------------------------------------------------------------*/
2568 geniCodeRightShift (operand * left, operand * right)
2572 ic = newiCode (RIGHT_OP, left, right);
2573 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2575 return IC_RESULT (ic);
2578 /*-----------------------------------------------------------------*/
2579 /* geniCodeLogic- logic code */
2580 /*-----------------------------------------------------------------*/
2582 geniCodeLogic (operand * left, operand * right, int op)
2586 sym_link *rtype = operandType (right);
2587 sym_link *ltype = operandType (left);
2589 /* left is integral type and right is literal then
2590 check if the literal value is within bounds */
2591 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2593 checkConstantRange(ltype,
2594 OP_VALUE(right), "compare operation", 1);
2597 ctype = usualBinaryConversions (&left, &right, TRUE);
2599 ic = newiCode (op, left, right);
2600 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2602 /* if comparing float
2603 and not a '==' || '!=' || '&&' || '||' (these
2605 if (IS_FLOAT(ctype) &&
2613 return IC_RESULT (ic);
2616 /*-----------------------------------------------------------------*/
2617 /* geniCodeUnary - for a a generic unary operation */
2618 /*-----------------------------------------------------------------*/
2620 geniCodeUnary (operand * op, int oper)
2622 iCode *ic = newiCode (oper, op, NULL);
2624 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2626 return IC_RESULT (ic);
2629 /*-----------------------------------------------------------------*/
2630 /* geniCodeConditional - geniCode for '?' ':' operation */
2631 /*-----------------------------------------------------------------*/
2633 geniCodeConditional (ast * tree,int lvl)
2636 symbol *falseLabel = newiTempLabel (NULL);
2637 symbol *exitLabel = newiTempLabel (NULL);
2638 operand *cond = ast2iCode (tree->left,lvl+1);
2639 operand *true, *false, *result;
2641 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2645 true = ast2iCode (tree->right->left,lvl+1);
2647 /* move the value to a new Operand */
2648 result = newiTempOperand (tree->right->ftype, 0);
2649 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2651 /* generate an unconditional goto */
2652 geniCodeGoto (exitLabel);
2654 /* now for the right side */
2655 geniCodeLabel (falseLabel);
2657 false = ast2iCode (tree->right->right,lvl+1);
2658 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2660 /* create the exit label */
2661 geniCodeLabel (exitLabel);
2666 /*-----------------------------------------------------------------*/
2667 /* geniCodeAssign - generate code for assignment */
2668 /*-----------------------------------------------------------------*/
2670 geniCodeAssign (operand * left, operand * right, int nosupdate)
2673 sym_link *ltype = operandType (left);
2674 sym_link *rtype = operandType (right);
2676 if (!left->isaddr && !IS_ITEMP (left))
2678 werror (E_LVALUE_REQUIRED, "assignment");
2682 /* left is integral type and right is literal then
2683 check if the literal value is within bounds */
2684 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2686 checkConstantRange(ltype,
2687 OP_VALUE(right), "= operation", 0);
2690 /* if the left & right type don't exactly match */
2691 /* if pointer set then make sure the check is
2692 done with the type & not the pointer */
2693 /* then cast rights type to left */
2695 /* first check the type for pointer assignement */
2696 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2697 compareType (ltype, rtype) <= 0)
2699 if (compareType (ltype->next, rtype) < 0)
2700 right = geniCodeCast (ltype->next, right, TRUE);
2702 else if (compareType (ltype, rtype) < 0)
2703 right = geniCodeCast (ltype, right, TRUE);
2705 /* if left is a true symbol & ! volatile
2706 create an assignment to temporary for
2707 the right & then assign this temporary
2708 to the symbol this is SSA . isn't it simple
2709 and folks have published mountains of paper on it */
2710 if (IS_TRUE_SYMOP (left) &&
2711 !isOperandVolatile (left, FALSE) &&
2712 isOperandGlobal (left))
2716 if (IS_TRUE_SYMOP (right))
2717 sym = OP_SYMBOL (right);
2718 ic = newiCode ('=', NULL, right);
2719 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2720 SPIL_LOC (right) = sym;
2724 ic = newiCode ('=', NULL, right);
2725 IC_RESULT (ic) = left;
2728 /* if left isgptr flag is set then support
2729 routine will be required */
2733 ic->nosupdate = nosupdate;
2737 /*-----------------------------------------------------------------*/
2738 /* geniCodeSEParms - generate code for side effecting fcalls */
2739 /*-----------------------------------------------------------------*/
2741 geniCodeSEParms (ast * parms,int lvl)
2746 if (parms->type == EX_OP && parms->opval.op == PARAM)
2748 geniCodeSEParms (parms->left,lvl);
2749 geniCodeSEParms (parms->right,lvl);
2753 /* hack don't like this but too lazy to think of
2755 if (IS_ADDRESS_OF_OP (parms))
2756 parms->left->lvalue = 1;
2758 if (IS_CAST_OP (parms) &&
2759 IS_PTR (parms->ftype) &&
2760 IS_ADDRESS_OF_OP (parms->right))
2761 parms->right->left->lvalue = 1;
2763 parms->opval.oprnd =
2764 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2766 parms->type = EX_OPERAND;
2769 /*-----------------------------------------------------------------*/
2770 /* geniCodeParms - generates parameters */
2771 /*-----------------------------------------------------------------*/
2773 geniCodeParms (ast * parms, value *argVals, int *stack,
2774 sym_link * fetype, symbol * func,int lvl)
2782 if (argVals==NULL) {
2784 argVals=FUNC_ARGS(func->type);
2787 /* if this is a param node then do the left & right */
2788 if (parms->type == EX_OP && parms->opval.op == PARAM)
2790 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2791 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2795 /* get the parameter value */
2796 if (parms->type == EX_OPERAND)
2797 pval = parms->opval.oprnd;
2800 /* maybe this else should go away ?? */
2801 /* hack don't like this but too lazy to think of
2803 if (IS_ADDRESS_OF_OP (parms))
2804 parms->left->lvalue = 1;
2806 if (IS_CAST_OP (parms) &&
2807 IS_PTR (parms->ftype) &&
2808 IS_ADDRESS_OF_OP (parms->right))
2809 parms->right->left->lvalue = 1;
2811 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2814 /* if register parm then make it a send */
2815 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2816 IFFUNC_ISBUILTIN(func->type))
2818 ic = newiCode (SEND, pval, NULL);
2819 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2824 /* now decide whether to push or assign */
2825 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2829 operand *top = operandFromSymbol (argVals->sym);
2830 /* clear useDef and other bitVectors */
2831 OP_USES (top) = OP_DEFS (top) = OP_SYMBOL(top)->clashes = NULL;
2832 geniCodeAssign (top, pval, 1);
2836 sym_link *p = operandType (pval);
2838 ic = newiCode (IPUSH, pval, NULL);
2840 /* update the stack adjustment */
2841 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2846 argVals=argVals->next;
2850 /*-----------------------------------------------------------------*/
2851 /* geniCodeCall - generates temp code for calling */
2852 /*-----------------------------------------------------------------*/
2854 geniCodeCall (operand * left, ast * parms,int lvl)
2858 sym_link *type, *etype;
2861 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2862 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2863 werror (E_FUNCTION_EXPECTED);
2867 /* take care of parameters with side-effecting
2868 function calls in them, this is required to take care
2869 of overlaying function parameters */
2870 geniCodeSEParms (parms,lvl);
2872 /* first the parameters */
2873 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2875 /* now call : if symbol then pcall */
2876 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2877 ic = newiCode (PCALL, left, NULL);
2879 ic = newiCode (CALL, left, NULL);
2881 type = copyLinkChain (operandType (left)->next);
2882 etype = getSpec (type);
2883 SPEC_EXTR (etype) = 0;
2884 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2888 /* stack adjustment after call */
2889 ic->parmBytes = stack;
2894 /*-----------------------------------------------------------------*/
2895 /* geniCodeReceive - generate intermediate code for "receive" */
2896 /*-----------------------------------------------------------------*/
2898 geniCodeReceive (value * args)
2900 /* for all arguments that are passed in registers */
2904 if (IS_REGPARM (args->etype))
2906 operand *opr = operandFromValue (args);
2908 symbol *sym = OP_SYMBOL (opr);
2911 /* we will use it after all optimizations
2912 and before liveRange calculation */
2913 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2916 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2917 options.stackAuto == 0 &&
2918 /* !TARGET_IS_DS390) */
2919 (!(options.model == MODEL_FLAT24)) )
2924 opl = newiTempOperand (args->type, 0);
2926 sym->reqv->key = sym->key;
2927 OP_SYMBOL (sym->reqv)->key = sym->key;
2928 OP_SYMBOL (sym->reqv)->isreqv = 1;
2929 OP_SYMBOL (sym->reqv)->islocal = 0;
2930 SPIL_LOC (sym->reqv) = sym;
2934 ic = newiCode (RECEIVE, NULL, NULL);
2935 currFunc->recvSize = getSize (sym->etype);
2936 IC_RESULT (ic) = opr;
2944 /*-----------------------------------------------------------------*/
2945 /* geniCodeFunctionBody - create the function body */
2946 /*-----------------------------------------------------------------*/
2948 geniCodeFunctionBody (ast * tree,int lvl)
2955 /* reset the auto generation */
2961 func = ast2iCode (tree->left,lvl+1);
2962 fetype = getSpec (operandType (func));
2964 savelineno = lineno;
2965 lineno = OP_SYMBOL (func)->lineDef;
2966 /* create an entry label */
2967 geniCodeLabel (entryLabel);
2968 lineno = savelineno;
2970 /* create a proc icode */
2971 ic = newiCode (FUNCTION, func, NULL);
2972 ic->lineno = OP_SYMBOL (func)->lineDef;
2976 /* for all parameters that are passed
2977 on registers add a "receive" */
2978 geniCodeReceive (tree->values.args);
2980 /* generate code for the body */
2981 ast2iCode (tree->right,lvl+1);
2983 /* create a label for return */
2984 geniCodeLabel (returnLabel);
2986 /* now generate the end proc */
2987 ic = newiCode (ENDFUNCTION, func, NULL);
2992 /*-----------------------------------------------------------------*/
2993 /* geniCodeReturn - gen icode for 'return' statement */
2994 /*-----------------------------------------------------------------*/
2996 geniCodeReturn (operand * op)
3000 /* if the operand is present force an rvalue */
3002 op = geniCodeRValue (op, FALSE);
3004 ic = newiCode (RETURN, op, NULL);
3008 /*-----------------------------------------------------------------*/
3009 /* geniCodeIfx - generates code for extended if statement */
3010 /*-----------------------------------------------------------------*/
3012 geniCodeIfx (ast * tree,int lvl)
3015 operand *condition = ast2iCode (tree->left,lvl+1);
3018 /* if condition is null then exit */
3022 condition = geniCodeRValue (condition, FALSE);
3024 cetype = getSpec (operandType (condition));
3025 /* if the condition is a literal */
3026 if (IS_LITERAL (cetype))
3028 if (floatFromVal (condition->operand.valOperand))
3030 if (tree->trueLabel)
3031 geniCodeGoto (tree->trueLabel);
3037 if (tree->falseLabel)
3038 geniCodeGoto (tree->falseLabel);
3045 if (tree->trueLabel)
3047 ic = newiCodeCondition (condition,
3052 if (tree->falseLabel)
3053 geniCodeGoto (tree->falseLabel);
3057 ic = newiCodeCondition (condition,
3064 ast2iCode (tree->right,lvl+1);
3067 /*-----------------------------------------------------------------*/
3068 /* geniCodeJumpTable - tries to create a jump table for switch */
3069 /*-----------------------------------------------------------------*/
3071 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3073 int min = 0, max = 0, t, cnt = 0;
3080 if (!tree || !caseVals)
3083 /* the criteria for creating a jump table is */
3084 /* all integer numbers between the maximum & minimum must */
3085 /* be present , the maximum value should not exceed 255 */
3086 min = max = (int) floatFromVal (vch = caseVals);
3087 sprintf (buffer, "_case_%d_%d",
3088 tree->values.switchVals.swNum,
3090 addSet (&labels, newiTempLabel (buffer));
3092 /* if there is only one case value then no need */
3093 if (!(vch = vch->next))
3098 if (((t = (int) floatFromVal (vch)) - max) != 1)
3100 sprintf (buffer, "_case_%d_%d",
3101 tree->values.switchVals.swNum,
3103 addSet (&labels, newiTempLabel (buffer));
3109 /* if the number of case statements <= 2 then */
3110 /* it is not economical to create the jump table */
3111 /* since two compares are needed for boundary conditions */
3112 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3115 if (tree->values.switchVals.swDefault)
3116 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3118 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3120 falseLabel = newiTempLabel (buffer);
3122 /* so we can create a jumptable */
3123 /* first we rule out the boundary conditions */
3124 /* if only optimization says so */
3125 if (!optimize.noJTabBoundary)
3127 sym_link *cetype = getSpec (operandType (cond));
3128 /* no need to check the lower bound if
3129 the condition is unsigned & minimum value is zero */
3130 if (!(min == 0 && SPEC_USIGN (cetype)))
3132 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3133 ic = newiCodeCondition (boundary, falseLabel, NULL);
3137 /* now for upper bounds */
3138 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3139 ic = newiCodeCondition (boundary, falseLabel, NULL);
3143 /* if the min is not zero then we no make it zero */
3146 cond = geniCodeSubtract (cond, operandFromLit (min));
3147 setOperandType (cond, UCHARTYPE);
3150 /* now create the jumptable */
3151 ic = newiCode (JUMPTABLE, NULL, NULL);
3152 IC_JTCOND (ic) = cond;
3153 IC_JTLABELS (ic) = labels;
3158 /*-----------------------------------------------------------------*/
3159 /* geniCodeSwitch - changes a switch to a if statement */
3160 /*-----------------------------------------------------------------*/
3162 geniCodeSwitch (ast * tree,int lvl)
3165 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3166 value *caseVals = tree->values.switchVals.swVals;
3167 symbol *trueLabel, *falseLabel;
3169 /* if we can make this a jump table */
3170 if (geniCodeJumpTable (cond, caseVals, tree))
3171 goto jumpTable; /* no need for the comparison */
3173 /* for the cases defined do */
3177 operand *compare = geniCodeLogic (cond,
3178 operandFromValue (caseVals),
3181 sprintf (buffer, "_case_%d_%d",
3182 tree->values.switchVals.swNum,
3183 (int) floatFromVal (caseVals));
3184 trueLabel = newiTempLabel (buffer);
3186 ic = newiCodeCondition (compare, trueLabel, NULL);
3188 caseVals = caseVals->next;
3193 /* if default is present then goto break else break */
3194 if (tree->values.switchVals.swDefault)
3195 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3197 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3199 falseLabel = newiTempLabel (buffer);
3200 geniCodeGoto (falseLabel);
3203 ast2iCode (tree->right,lvl+1);
3206 /*-----------------------------------------------------------------*/
3207 /* geniCodeInline - intermediate code for inline assembler */
3208 /*-----------------------------------------------------------------*/
3210 geniCodeInline (ast * tree)
3214 ic = newiCode (INLINEASM, NULL, NULL);
3215 IC_INLINE (ic) = tree->values.inlineasm;
3219 /*-----------------------------------------------------------------*/
3220 /* geniCodeArrayInit - intermediate code for array initializer */
3221 /*-----------------------------------------------------------------*/
3223 geniCodeArrayInit (ast * tree, operand *array)
3227 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3228 ic = newiCode (ARRAYINIT, array, NULL);
3229 IC_ARRAYILIST (ic) = tree->values.constlist;
3231 operand *left=newOperand(), *right=newOperand();
3232 left->type=right->type=SYMBOL;
3233 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3234 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3235 ic = newiCode (ARRAYINIT, left, right);
3240 /*-----------------------------------------------------------------*/
3241 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3242 /* particular case. Ie : assigning or dereferencing array or ptr */
3243 /*-----------------------------------------------------------------*/
3244 set * lvaluereqSet = NULL;
3245 typedef struct lvalItem
3252 /*-----------------------------------------------------------------*/
3253 /* addLvaluereq - add a flag for lvalreq for current ast level */
3254 /*-----------------------------------------------------------------*/
3255 void addLvaluereq(int lvl)
3257 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3260 addSetHead(&lvaluereqSet,lpItem);
3263 /*-----------------------------------------------------------------*/
3264 /* delLvaluereq - del a flag for lvalreq for current ast level */
3265 /*-----------------------------------------------------------------*/
3269 lpItem = getSet(&lvaluereqSet);
3270 if(lpItem) Safe_free(lpItem);
3272 /*-----------------------------------------------------------------*/
3273 /* clearLvaluereq - clear lvalreq flag */
3274 /*-----------------------------------------------------------------*/
3275 void clearLvaluereq()
3278 lpItem = peekSet(lvaluereqSet);
3279 if(lpItem) lpItem->req = 0;
3281 /*-----------------------------------------------------------------*/
3282 /* getLvaluereq - get the last lvalreq level */
3283 /*-----------------------------------------------------------------*/
3284 int getLvaluereqLvl()
3287 lpItem = peekSet(lvaluereqSet);
3288 if(lpItem) return lpItem->lvl;
3291 /*-----------------------------------------------------------------*/
3292 /* isLvaluereq - is lvalreq valid for this level ? */
3293 /*-----------------------------------------------------------------*/
3294 int isLvaluereq(int lvl)
3297 lpItem = peekSet(lvaluereqSet);
3298 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3302 /*-----------------------------------------------------------------*/
3303 /* ast2iCode - creates an icodeList from an ast */
3304 /*-----------------------------------------------------------------*/
3306 ast2iCode (ast * tree,int lvl)
3308 operand *left = NULL;
3309 operand *right = NULL;
3312 /* set the global variables for filename & line number */
3314 filename = tree->filename;
3316 lineno = tree->lineno;
3318 block = tree->block;
3320 scopeLevel = tree->level;
3322 if (tree->type == EX_VALUE)
3323 return operandFromValue (tree->opval.val);
3325 if (tree->type == EX_LINK)
3326 return operandFromLink (tree->opval.lnk);
3328 /* if we find a nullop */
3329 if (tree->type == EX_OP &&
3330 (tree->opval.op == NULLOP ||
3331 tree->opval.op == BLOCK))
3333 ast2iCode (tree->left,lvl+1);
3334 ast2iCode (tree->right,lvl+1);
3338 /* special cases for not evaluating */
3339 if (tree->opval.op != ':' &&
3340 tree->opval.op != '?' &&
3341 tree->opval.op != CALL &&
3342 tree->opval.op != IFX &&
3343 tree->opval.op != LABEL &&
3344 tree->opval.op != GOTO &&
3345 tree->opval.op != SWITCH &&
3346 tree->opval.op != FUNCTION &&
3347 tree->opval.op != INLINEASM)
3350 if (IS_ASSIGN_OP (tree->opval.op) ||
3351 IS_DEREF_OP (tree) ||
3352 (tree->opval.op == '&' && !tree->right) ||
3353 tree->opval.op == PTR_OP)
3356 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3357 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3360 left = operandFromAst (tree->left,lvl);
3362 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3363 left = geniCodeRValue (left, TRUE);
3367 left = operandFromAst (tree->left,lvl);
3369 if (tree->opval.op == INC_OP ||
3370 tree->opval.op == DEC_OP)
3373 right = operandFromAst (tree->right,lvl);
3378 right = operandFromAst (tree->right,lvl);
3382 /* now depending on the type of operand */
3383 /* this will be a biggy */
3384 switch (tree->opval.op)
3387 case '[': /* array operation */
3389 //sym_link *ltype = operandType (left);
3390 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3391 left = geniCodeRValue (left, FALSE);
3392 right = geniCodeRValue (right, TRUE);
3395 return geniCodeArray (left, right,lvl);
3397 case '.': /* structure dereference */
3398 if (IS_PTR (operandType (left)))
3399 left = geniCodeRValue (left, TRUE);
3401 left = geniCodeRValue (left, FALSE);
3403 return geniCodeStruct (left, right, tree->lvalue);
3405 case PTR_OP: /* structure pointer dereference */
3408 pType = operandType (left);
3409 left = geniCodeRValue (left, TRUE);
3411 setOClass (pType, getSpec (operandType (left)));
3414 return geniCodeStruct (left, right, tree->lvalue);
3416 case INC_OP: /* increment operator */
3418 return geniCodePostInc (left);
3420 return geniCodePreInc (right);
3422 case DEC_OP: /* decrement operator */
3424 return geniCodePostDec (left);
3426 return geniCodePreDec (right);
3428 case '&': /* bitwise and or address of operator */
3430 { /* this is a bitwise operator */
3431 left = geniCodeRValue (left, FALSE);
3432 right = geniCodeRValue (right, FALSE);
3433 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3436 return geniCodeAddressOf (left);
3438 case '|': /* bitwise or & xor */
3440 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3441 geniCodeRValue (right, FALSE),
3446 return geniCodeDivision (geniCodeRValue (left, FALSE),
3447 geniCodeRValue (right, FALSE));
3450 return geniCodeModulus (geniCodeRValue (left, FALSE),
3451 geniCodeRValue (right, FALSE));
3454 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3455 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3457 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3461 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3462 geniCodeRValue (right, FALSE));
3464 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3468 return geniCodeAdd (geniCodeRValue (left, FALSE),
3469 geniCodeRValue (right, FALSE),lvl, 0);
3471 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3474 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3475 geniCodeRValue (right, FALSE));
3478 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3479 geniCodeRValue (right, FALSE));
3481 return geniCodeCast (operandType (left),
3482 geniCodeRValue (right, FALSE), FALSE);
3488 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3492 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3493 setOperandType (op, UCHARTYPE);
3504 return geniCodeLogic (geniCodeRValue (left, FALSE),
3505 geniCodeRValue (right, FALSE),
3508 return geniCodeConditional (tree,lvl);
3511 return operandFromLit (getSize (tree->right->ftype));
3515 sym_link *rtype = operandType (right);
3516 sym_link *ltype = operandType (left);
3517 if (IS_PTR (rtype) && IS_ITEMP (right)
3518 && right->isaddr && compareType (rtype->next, ltype) == 1)
3519 right = geniCodeRValue (right, TRUE);
3521 right = geniCodeRValue (right, FALSE);
3523 geniCodeAssign (left, right, 0);
3528 geniCodeAssign (left,
3529 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3531 geniCodeRValue (right, FALSE),FALSE), 0);
3535 geniCodeAssign (left,
3536 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3538 geniCodeRValue (right, FALSE)), 0);
3541 geniCodeAssign (left,
3542 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3544 geniCodeRValue (right, FALSE)), 0);
3547 sym_link *rtype = operandType (right);
3548 sym_link *ltype = operandType (left);
3549 if (IS_PTR (rtype) && IS_ITEMP (right)
3550 && right->isaddr && compareType (rtype->next, ltype) == 1)
3551 right = geniCodeRValue (right, TRUE);
3553 right = geniCodeRValue (right, FALSE);
3556 return geniCodeAssign (left,
3557 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3563 sym_link *rtype = operandType (right);
3564 sym_link *ltype = operandType (left);
3565 if (IS_PTR (rtype) && IS_ITEMP (right)
3566 && right->isaddr && compareType (rtype->next, ltype) == 1)
3568 right = geniCodeRValue (right, TRUE);
3572 right = geniCodeRValue (right, FALSE);
3575 geniCodeAssign (left,
3576 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3582 geniCodeAssign (left,
3583 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3585 geniCodeRValue (right, FALSE)), 0);
3588 geniCodeAssign (left,
3589 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3591 geniCodeRValue (right, FALSE)), 0);
3594 geniCodeAssign (left,
3595 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3597 geniCodeRValue (right, FALSE),
3599 operandType (left)), 0);
3602 geniCodeAssign (left,
3603 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3605 geniCodeRValue (right, FALSE),
3607 operandType (left)), 0);
3610 geniCodeAssign (left,
3611 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3613 geniCodeRValue (right, FALSE),
3615 operandType (left)), 0);
3617 return geniCodeRValue (right, FALSE);
3620 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3623 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3624 return ast2iCode (tree->right,lvl+1);
3627 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3628 return ast2iCode (tree->right,lvl+1);
3631 geniCodeFunctionBody (tree,lvl);
3635 geniCodeReturn (right);
3639 geniCodeIfx (tree,lvl);
3643 geniCodeSwitch (tree,lvl);
3647 geniCodeInline (tree);
3651 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3658 /*-----------------------------------------------------------------*/
3659 /* reverseICChain - gets from the list and creates a linkedlist */
3660 /*-----------------------------------------------------------------*/
3667 while ((loop = getSet (&iCodeChain)))
3679 /*-----------------------------------------------------------------*/
3680 /* iCodeFromAst - given an ast will convert it to iCode */
3681 /*-----------------------------------------------------------------*/
3683 iCodeFromAst (ast * tree)
3685 returnLabel = newiTempLabel ("_return");
3686 entryLabel = newiTempLabel ("_entry");
3688 return reverseiCChain ();