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,
233 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
234 OP_SYMBOL(op)->ruonly
238 printTypeChain (operandType (op), file);
239 if (SPIL_LOC (op) && IS_ITEMP (op))
240 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
245 /* if assigned to registers */
246 if (OP_SYMBOL (op)->nRegs)
248 if (OP_SYMBOL (op)->isspilt)
250 if (!OP_SYMBOL (op)->remat)
251 if (OP_SYMBOL (op)->usl.spillLoc)
252 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
253 OP_SYMBOL (op)->usl.spillLoc->rname :
254 OP_SYMBOL (op)->usl.spillLoc->name));
256 fprintf (file, "[err]");
258 fprintf (file, "[remat]");
264 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
265 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
270 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
271 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
272 /* if assigned to registers */
273 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
277 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
278 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
279 OP_SYMBOL (op)->regs[i]->name :
288 printTypeChain (op->operand.typeOperand, file);
294 fprintf (file, "\n");
299 /*-----------------------------------------------------------------*/
300 /* print functions */
301 /*-----------------------------------------------------------------*/
302 PRINTFUNC (picGetValueAtAddr)
305 printOperand (IC_RESULT (ic), of);
308 printOperand (IC_LEFT (ic), of);
314 PRINTFUNC (picSetValueAtAddr)
318 printOperand (IC_LEFT (ic), of);
319 fprintf (of, "] = ");
320 printOperand (IC_RIGHT (ic), of);
324 PRINTFUNC (picAddrOf)
327 printOperand (IC_RESULT (ic), of);
328 if (IS_ITEMP (IC_LEFT (ic)))
331 fprintf (of, " = &[");
332 printOperand (IC_LEFT (ic), of);
335 if (IS_ITEMP (IC_LEFT (ic)))
336 fprintf (of, " offsetAdd ");
339 printOperand (IC_RIGHT (ic), of);
341 if (IS_ITEMP (IC_LEFT (ic)))
347 PRINTFUNC (picJumpTable)
352 fprintf (of, "%s\t", s);
353 printOperand (IC_JTCOND (ic), of);
355 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
356 sym = setNextItem (IC_JTLABELS (ic)))
357 fprintf (of, "\t\t\t%s\n", sym->name);
360 PRINTFUNC (picGeneric)
363 printOperand (IC_RESULT (ic), of);
365 printOperand (IC_LEFT (ic), of);
366 fprintf (of, " %s ", s);
367 printOperand (IC_RIGHT (ic), of);
371 PRINTFUNC (picGenericOne)
376 printOperand (IC_RESULT (ic), of);
382 fprintf (of, "%s ", s);
383 printOperand (IC_LEFT (ic), of);
386 if (!IC_RESULT (ic) && !IC_LEFT (ic))
395 printOperand (IC_RESULT (ic), of);
397 printOperand (IC_LEFT (ic), of);
398 printOperand (IC_RIGHT (ic), of);
403 PRINTFUNC (picAssign)
407 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
410 printOperand (IC_RESULT (ic), of);
412 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
415 fprintf (of, " %s ", s);
416 printOperand (IC_RIGHT (ic), of);
423 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
429 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
436 printOperand (IC_COND (ic), of);
439 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
442 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
444 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
448 PRINTFUNC (picInline)
450 fprintf (of, "%s", IC_INLINE (ic));
453 PRINTFUNC (picReceive)
455 printOperand (IC_RESULT (ic), of);
456 fprintf (of, " = %s ", s);
457 printOperand (IC_LEFT (ic), of);
461 /*-----------------------------------------------------------------*/
462 /* piCode - prints one iCode */
463 /*-----------------------------------------------------------------*/
465 piCode (void *item, FILE * of)
473 icTab = getTableEntry (ic->op);
474 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
475 ic->filename, ic->lineno,
476 ic->seq, ic->key, ic->depth, ic->supportRtn);
477 icTab->iCodePrint (of, ic, icTab->printName);
483 printiCChain(ic,stdout);
485 /*-----------------------------------------------------------------*/
486 /* printiCChain - prints intermediate code for humans */
487 /*-----------------------------------------------------------------*/
489 printiCChain (iCode * icChain, FILE * of)
496 for (loop = icChain; loop; loop = loop->next)
498 if ((icTab = getTableEntry (loop->op)))
500 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
501 loop->filename, loop->lineno,
502 loop->seq, loop->key, loop->depth, loop->supportRtn);
504 icTab->iCodePrint (of, loop, icTab->printName);
510 /*-----------------------------------------------------------------*/
511 /* newOperand - allocate, init & return a new iCode */
512 /*-----------------------------------------------------------------*/
518 op = Safe_alloc ( sizeof (operand));
524 /*-----------------------------------------------------------------*/
525 /* newiCode - create and return a new iCode entry initialised */
526 /*-----------------------------------------------------------------*/
528 newiCode (int op, operand * left, operand * right)
532 ic = Safe_alloc ( sizeof (iCode));
535 ic->filename = filename;
537 ic->level = scopeLevel;
539 ic->key = iCodeKey++;
541 IC_RIGHT (ic) = right;
546 /*-----------------------------------------------------------------*/
547 /* newiCode for conditional statements */
548 /*-----------------------------------------------------------------*/
550 newiCodeCondition (operand * condition,
556 if (IS_VOID(operandType(condition))) {
557 werror(E_VOID_VALUE_USED);
560 ic = newiCode (IFX, NULL, NULL);
561 IC_COND (ic) = condition;
562 IC_TRUE (ic) = trueLabel;
563 IC_FALSE (ic) = falseLabel;
567 /*-----------------------------------------------------------------*/
568 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
569 /*-----------------------------------------------------------------*/
571 newiCodeLabelGoto (int op, symbol * label)
575 ic = newiCode (op, NULL, NULL);
577 ic->argLabel.label = label;
579 IC_RIGHT (ic) = NULL;
580 IC_RESULT (ic) = NULL;
584 /*-----------------------------------------------------------------*/
585 /* newiTemp - allocate & return a newItemp Variable */
586 /*-----------------------------------------------------------------*/
593 sprintf (buffer, "%s", s);
595 sprintf (buffer, "iTemp%d", iTempNum++);
596 itmp = newSymbol (buffer, 1);
597 strcpy (itmp->rname, itmp->name);
603 /*-----------------------------------------------------------------*/
604 /* newiTempLabel - creates a temp variable label */
605 /*-----------------------------------------------------------------*/
607 newiTempLabel (char *s)
611 /* check if this alredy exists */
612 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
616 itmplbl = newSymbol (s, 1);
619 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
620 itmplbl = newSymbol (buffer, 1);
625 itmplbl->key = labelKey++;
626 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
630 /*-----------------------------------------------------------------*/
631 /* newiTempPreheaderLabel - creates a new preheader label */
632 /*-----------------------------------------------------------------*/
634 newiTempPreheaderLabel ()
638 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
639 itmplbl = newSymbol (buffer, 1);
643 itmplbl->key = labelKey++;
644 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
649 /*-----------------------------------------------------------------*/
650 /* initiCode - initialises some iCode related stuff */
651 /*-----------------------------------------------------------------*/
658 /*-----------------------------------------------------------------*/
659 /* copyiCode - make a copy of the iCode given */
660 /*-----------------------------------------------------------------*/
662 copyiCode (iCode * ic)
664 iCode *nic = newiCode (ic->op, NULL, NULL);
666 nic->lineno = ic->lineno;
667 nic->filename = ic->filename;
668 nic->block = ic->block;
669 nic->level = ic->level;
670 nic->parmBytes = ic->parmBytes;
672 /* deal with the special cases first */
676 IC_COND (nic) = operandFromOperand (IC_COND (ic));
677 IC_TRUE (nic) = IC_TRUE (ic);
678 IC_FALSE (nic) = IC_FALSE (ic);
682 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
683 IC_JTLABELS (nic) = IC_JTLABELS (ic);
688 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
689 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
693 IC_INLINE (nic) = IC_INLINE (ic);
697 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
701 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
702 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
703 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
709 /*-----------------------------------------------------------------*/
710 /* getTableEntry - gets the table entry for the given operator */
711 /*-----------------------------------------------------------------*/
713 getTableEntry (int oper)
717 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
718 if (oper == codeTable[i].icode)
719 return &codeTable[i];
724 /*-----------------------------------------------------------------*/
725 /* newiTempOperand - new intermediate temp operand */
726 /*-----------------------------------------------------------------*/
728 newiTempOperand (sym_link * type, char throwType)
731 operand *op = newOperand ();
735 itmp = newiTemp (NULL);
737 etype = getSpec (type);
739 if (IS_LITERAL (etype))
742 /* copy the type information */
744 itmp->etype = getSpec (itmp->type = (throwType ? type :
745 copyLinkChain (type)));
746 if (IS_LITERAL (itmp->etype))
748 SPEC_SCLS (itmp->etype) = S_REGISTER;
749 SPEC_OCLS (itmp->etype) = reg;
752 op->operand.symOperand = itmp;
753 op->key = itmp->key = ++operandKey;
757 /*-----------------------------------------------------------------*/
758 /* operandType - returns the type chain for an operand */
759 /*-----------------------------------------------------------------*/
761 operandType (operand * op)
763 /* depending on type of operand */
768 return op->operand.valOperand->type;
771 return op->operand.symOperand->type;
774 return op->operand.typeOperand;
776 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
777 " operand type not known ");
778 assert (0); /* should never come here */
779 /* Just to keep the compiler happy */
780 return (sym_link *) 0;
784 /*-----------------------------------------------------------------*/
785 /* isParamterToCall - will return 1 if op is a parameter to args */
786 /*-----------------------------------------------------------------*/
788 isParameterToCall (value * args, operand * op)
795 isSymbolEqual (op->operand.symOperand, tval->sym))
802 /*-----------------------------------------------------------------*/
803 /* isOperandGlobal - return 1 if operand is a global variable */
804 /*-----------------------------------------------------------------*/
806 isOperandGlobal (operand * op)
814 if (op->type == SYMBOL &&
815 (op->operand.symOperand->level == 0 ||
816 IS_STATIC (op->operand.symOperand->etype) ||
817 IS_EXTERN (op->operand.symOperand->etype))
824 /*-----------------------------------------------------------------*/
825 /* isOperandVolatile - return 1 if the operand is volatile */
826 /*-----------------------------------------------------------------*/
828 isOperandVolatile (operand * op, bool chkTemp)
833 if (IS_ITEMP (op) && !chkTemp)
836 opetype = getSpec (optype = operandType (op));
838 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
841 if (IS_VOLATILE (opetype))
846 /*-----------------------------------------------------------------*/
847 /* isOperandLiteral - returns 1 if an operand contains a literal */
848 /*-----------------------------------------------------------------*/
850 isOperandLiteral (operand * op)
857 opetype = getSpec (operandType (op));
859 if (IS_LITERAL (opetype))
865 /*-----------------------------------------------------------------*/
866 /* isOperandInFarSpace - will return true if operand is in farSpace */
867 /*-----------------------------------------------------------------*/
869 isOperandInFarSpace (operand * op)
879 if (!IS_TRUE_SYMOP (op))
882 etype = SPIL_LOC (op)->etype;
888 etype = getSpec (operandType (op));
890 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
893 /*------------------------------------------------------------------*/
894 /* isOperandInDirSpace - will return true if operand is in dirSpace */
895 /*------------------------------------------------------------------*/
897 isOperandInDirSpace (operand * op)
907 if (!IS_TRUE_SYMOP (op))
910 etype = SPIL_LOC (op)->etype;
916 etype = getSpec (operandType (op));
918 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
921 /*-----------------------------------------------------------------*/
922 /* isOperandOnStack - will return true if operand is on stack */
923 /*-----------------------------------------------------------------*/
926 isOperandOnStack (operand * op)
936 etype = getSpec (operandType (op));
938 return ((IN_STACK (etype)) ? TRUE : FALSE);
942 isOperandOnStack (operand * op)
952 etype = getSpec (operandType (op));
953 if (IN_STACK (etype) ||
954 OP_SYMBOL(op)->onStack ||
955 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
962 /*-----------------------------------------------------------------*/
963 /* operandLitValue - literal value of an operand */
964 /*-----------------------------------------------------------------*/
966 operandLitValue (operand * op)
968 assert (isOperandLiteral (op));
970 return floatFromVal (op->operand.valOperand);
973 /*-----------------------------------------------------------------*/
974 /* getBuiltInParms - returns parameters to a builtin functions */
975 /*-----------------------------------------------------------------*/
976 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
981 /* builtin functions uses only SEND for parameters */
982 while (ic->op != CALL) {
983 assert(ic->op == SEND && ic->builtinSEND);
984 ic->generated = 1; /* mark the icode as generated */
985 parms[*pcount] = IC_LEFT(ic);
991 /* make sure this is a builtin function call */
992 assert(IS_SYMOP(IC_LEFT(ic)));
993 ftype = operandType(IC_LEFT(ic));
994 assert(IFFUNC_ISBUILTIN(ftype));
998 /*-----------------------------------------------------------------*/
999 /* operandOperation - perforoms operations on operands */
1000 /*-----------------------------------------------------------------*/
1002 operandOperation (operand * left, operand * right,
1003 int op, sym_link * type)
1005 sym_link *let , *ret=NULL;
1006 operand *retval = (operand *) 0;
1008 assert (isOperandLiteral (left));
1009 let = getSpec(operandType(left));
1011 assert (isOperandLiteral (right));
1012 ret = getSpec(operandType(left));
1018 retval = operandFromValue (valCastLiteral (type,
1019 operandLitValue (left) +
1020 operandLitValue (right)));
1023 retval = operandFromValue (valCastLiteral (type,
1024 operandLitValue (left) -
1025 operandLitValue (right)));
1028 retval = operandFromValue (valCastLiteral (type,
1029 operandLitValue (left) *
1030 operandLitValue (right)));
1033 if ((unsigned long) operandLitValue (right) == 0)
1035 werror (E_DIVIDE_BY_ZERO);
1040 retval = operandFromValue (valCastLiteral (type,
1041 operandLitValue (left) /
1042 operandLitValue (right)));
1045 if ((unsigned long) operandLitValue (right) == 0) {
1046 werror (E_DIVIDE_BY_ZERO);
1050 retval = operandFromLit ((SPEC_USIGN(let) ?
1051 (unsigned long) operandLitValue (left) :
1052 (long) operandLitValue (left)) %
1054 (unsigned long) operandLitValue (right) :
1055 (long) operandLitValue (right)));
1059 retval = operandFromLit ((SPEC_USIGN(let) ?
1060 (unsigned long) operandLitValue (left) :
1061 (long) operandLitValue (left)) <<
1063 (unsigned long) operandLitValue (right) :
1064 (long) operandLitValue (right)));
1067 retval = operandFromLit ((SPEC_USIGN(let) ?
1068 (unsigned long) operandLitValue (left) :
1069 (long) operandLitValue (left)) >>
1071 (unsigned long) operandLitValue (right) :
1072 (long) operandLitValue (right)));
1075 retval = operandFromLit (operandLitValue (left) ==
1076 operandLitValue (right));
1079 retval = operandFromLit (operandLitValue (left) <
1080 operandLitValue (right));
1083 retval = operandFromLit (operandLitValue (left) <=
1084 operandLitValue (right));
1087 retval = operandFromLit (operandLitValue (left) !=
1088 operandLitValue (right));
1091 retval = operandFromLit (operandLitValue (left) >
1092 operandLitValue (right));
1095 retval = operandFromLit (operandLitValue (left) >=
1096 operandLitValue (right));
1099 retval = operandFromLit ((long)operandLitValue(left) &
1100 (long)operandLitValue(right));
1103 retval = operandFromLit ((long)operandLitValue (left) |
1104 (long)operandLitValue (right));
1107 retval = operandFromLit ((long)operandLitValue (left) ^
1108 (long)operandLitValue (right));
1111 retval = operandFromLit (operandLitValue (left) &&
1112 operandLitValue (right));
1115 retval = operandFromLit (operandLitValue (left) ||
1116 operandLitValue (right));
1120 long i = (long) operandLitValue (left);
1122 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1128 long i = (long) operandLitValue (left);
1130 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1136 retval = operandFromLit (-1 * operandLitValue (left));
1140 retval = operandFromLit (~((long) operandLitValue (left)));
1144 retval = operandFromLit (!operandLitValue (left));
1148 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1149 " operandOperation invalid operator ");
1157 /*-----------------------------------------------------------------*/
1158 /* isOperandEqual - compares two operand & return 1 if they r = */
1159 /*-----------------------------------------------------------------*/
1161 isOperandEqual (operand * left, operand * right)
1163 /* if the pointers are equal then they are equal */
1167 /* if either of them null then false */
1168 if (!left || !right)
1171 if (left->type != right->type)
1174 if (IS_SYMOP (left) && IS_SYMOP (right))
1175 return left->key == right->key;
1177 /* if types are the same */
1181 return isSymbolEqual (left->operand.symOperand,
1182 right->operand.symOperand);
1184 return (floatFromVal (left->operand.valOperand) ==
1185 floatFromVal (right->operand.valOperand));
1187 if (compareType (left->operand.typeOperand,
1188 right->operand.typeOperand) == 1)
1195 /*-------------------------------------------------------------------*/
1196 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1197 /*-------------------------------------------------------------------*/
1199 isiCodeEqual (iCode * left, iCode * right)
1201 /* if the same pointer */
1205 /* if either of them null */
1206 if (!left || !right)
1209 /* if operand are the same */
1210 if (left->op == right->op)
1213 /* compare all the elements depending on type */
1214 if (left->op != IFX)
1216 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1218 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1224 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1226 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1228 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1237 /*-----------------------------------------------------------------*/
1238 /* newiTempFromOp - create a temp Operand with same attributes */
1239 /*-----------------------------------------------------------------*/
1241 newiTempFromOp (operand * op)
1251 nop = newiTempOperand (operandType (op), TRUE);
1252 nop->isaddr = op->isaddr;
1253 nop->isvolatile = op->isvolatile;
1254 nop->isGlobal = op->isGlobal;
1255 nop->isLiteral = op->isLiteral;
1256 nop->usesDefs = op->usesDefs;
1257 nop->isParm = op->isParm;
1261 /*-----------------------------------------------------------------*/
1262 /* operand from operand - creates an operand holder for the type */
1263 /*-----------------------------------------------------------------*/
1265 operandFromOperand (operand * op)
1271 nop = newOperand ();
1272 nop->type = op->type;
1273 nop->isaddr = op->isaddr;
1275 nop->isvolatile = op->isvolatile;
1276 nop->isGlobal = op->isGlobal;
1277 nop->isLiteral = op->isLiteral;
1278 nop->usesDefs = op->usesDefs;
1279 nop->isParm = op->isParm;
1284 nop->operand.symOperand = op->operand.symOperand;
1287 nop->operand.valOperand = op->operand.valOperand;
1290 nop->operand.typeOperand = op->operand.typeOperand;
1297 /*-----------------------------------------------------------------*/
1298 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1299 /*-----------------------------------------------------------------*/
1301 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1303 operand *nop = operandFromOperand (op);
1305 if (nop->type == SYMBOL)
1307 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1308 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1314 /*-----------------------------------------------------------------*/
1315 /* operandFromSymbol - creates an operand from a symbol */
1316 /*-----------------------------------------------------------------*/
1318 operandFromSymbol (symbol * sym)
1323 /* if the symbol's type is a literal */
1324 /* then it is an enumerator type */
1325 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1326 return operandFromValue (valFromType (sym->etype));
1329 sym->key = ++operandKey;
1331 /* if this an implicit variable, means struct/union */
1332 /* member so just return it */
1333 if (sym->implicit || IS_FUNC (sym->type))
1337 op->operand.symOperand = sym;
1339 op->isvolatile = isOperandVolatile (op, TRUE);
1340 op->isGlobal = isOperandGlobal (op);
1344 /* under the following conditions create a
1345 register equivalent for a local symbol */
1346 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1347 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1348 (!(options.model == MODEL_FLAT24)) ) &&
1349 options.stackAuto == 0)
1352 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1353 !IS_FUNC (sym->type) && /* not a function */
1354 !sym->_isparm && /* not a parameter */
1355 sym->level && /* is a local variable */
1356 !sym->addrtaken && /* whose address has not been taken */
1357 !sym->reqv && /* does not already have a reg equivalence */
1358 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1359 !IS_STATIC (sym->etype) && /* and not declared static */
1360 !sym->islbl && /* not a label */
1361 ok && /* farspace check */
1362 !IS_BITVAR (sym->etype) /* not a bit variable */
1366 /* we will use it after all optimizations
1367 and before liveRange calculation */
1368 sym->reqv = newiTempOperand (sym->type, 0);
1369 sym->reqv->key = sym->key;
1370 OP_SYMBOL (sym->reqv)->key = sym->key;
1371 OP_SYMBOL (sym->reqv)->isreqv = 1;
1372 OP_SYMBOL (sym->reqv)->islocal = 1;
1373 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1374 SPIL_LOC (sym->reqv) = sym;
1377 if (!IS_AGGREGATE (sym->type))
1381 op->operand.symOperand = sym;
1384 op->isvolatile = isOperandVolatile (op, TRUE);
1385 op->isGlobal = isOperandGlobal (op);
1386 op->isPtr = IS_PTR (operandType (op));
1387 op->isParm = sym->_isparm;
1392 /* itemp = &[_symbol] */
1394 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1395 IC_LEFT (ic)->type = SYMBOL;
1396 IC_LEFT (ic)->operand.symOperand = sym;
1397 IC_LEFT (ic)->key = sym->key;
1398 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1399 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1400 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1403 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1404 if (IS_ARRAY (sym->type))
1406 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1407 IC_RESULT (ic)->isaddr = 0;
1410 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1414 return IC_RESULT (ic);
1417 /*-----------------------------------------------------------------*/
1418 /* operandFromValue - creates an operand from value */
1419 /*-----------------------------------------------------------------*/
1421 operandFromValue (value * val)
1425 /* if this is a symbol then do the symbol thing */
1427 return operandFromSymbol (val->sym);
1429 /* this is not a symbol */
1432 op->operand.valOperand = val;
1433 op->isLiteral = isOperandLiteral (op);
1437 /*-----------------------------------------------------------------*/
1438 /* operandFromLink - operand from typeChain */
1439 /*-----------------------------------------------------------------*/
1441 operandFromLink (sym_link * type)
1445 /* operand from sym_link */
1451 op->operand.typeOperand = copyLinkChain (type);
1455 /*-----------------------------------------------------------------*/
1456 /* operandFromLit - makes an operand from a literal value */
1457 /*-----------------------------------------------------------------*/
1459 operandFromLit (double i)
1461 return operandFromValue (valueFromLit (i));
1464 /*-----------------------------------------------------------------*/
1465 /* operandFromAst - creates an operand from an ast */
1466 /*-----------------------------------------------------------------*/
1468 operandFromAst (ast * tree,int lvl)
1474 /* depending on type do */
1478 return ast2iCode (tree,lvl+1);
1482 return operandFromValue (tree->opval.val);
1486 return operandFromLink (tree->opval.lnk);
1490 /* Just to keep the comiler happy */
1491 return (operand *) 0;
1494 /*-----------------------------------------------------------------*/
1495 /* setOperandType - sets the operand's type to the given type */
1496 /*-----------------------------------------------------------------*/
1498 setOperandType (operand * op, sym_link * type)
1500 /* depending on the type of operand */
1505 op->operand.valOperand->etype =
1506 getSpec (op->operand.valOperand->type =
1507 copyLinkChain (type));
1511 if (op->operand.symOperand->isitmp)
1512 op->operand.symOperand->etype =
1513 getSpec (op->operand.symOperand->type =
1514 copyLinkChain (type));
1516 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1517 "attempt to modify type of source");
1521 op->operand.typeOperand = copyLinkChain (type);
1526 /*-----------------------------------------------------------------*/
1527 /* Get size in byte of ptr need to access an array */
1528 /*-----------------------------------------------------------------*/
1530 getArraySizePtr (operand * op)
1532 sym_link *ltype = operandType(op);
1536 int size = getSize(ltype);
1537 return(IS_GENPTR(ltype)?(size-1):size);
1542 sym_link *letype = getSpec(ltype);
1543 switch (PTR_TYPE (SPEC_OCLS (letype)))
1555 return (GPTRSIZE-1);
1564 /*-----------------------------------------------------------------*/
1565 /* perform "usual unary conversions" */
1566 /*-----------------------------------------------------------------*/
1568 usualUnaryConversions (operand * op)
1570 if (IS_INTEGRAL (operandType (op)))
1572 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1575 return geniCodeCast (INTTYPE, op, TRUE);
1581 /*-----------------------------------------------------------------*/
1582 /* perform "usual binary conversions" */
1583 /*-----------------------------------------------------------------*/
1585 usualBinaryConversions (operand ** op1, operand ** op2)
1588 sym_link *rtype = operandType (*op2);
1589 sym_link *ltype = operandType (*op1);
1591 ctype = computeType (ltype, rtype);
1592 *op1 = geniCodeCast (ctype, *op1, TRUE);
1593 *op2 = geniCodeCast (ctype, *op2, TRUE);
1598 /*-----------------------------------------------------------------*/
1599 /* geniCodeValueAtAddress - generate intermeditate code for value */
1601 /*-----------------------------------------------------------------*/
1603 geniCodeRValue (operand * op, bool force)
1606 sym_link *type = operandType (op);
1607 sym_link *etype = getSpec (type);
1609 /* if this is an array & already */
1610 /* an address then return this */
1611 if (IS_AGGREGATE (type) ||
1612 (IS_PTR (type) && !force && !op->isaddr))
1613 return operandFromOperand (op);
1615 /* if this is not an address then must be */
1616 /* rvalue already so return this one */
1620 /* if this is not a temp symbol then */
1621 if (!IS_ITEMP (op) &&
1623 !IN_FARSPACE (SPEC_OCLS (etype)))
1625 op = operandFromOperand (op);
1630 if (IS_SPEC (type) &&
1631 IS_TRUE_SYMOP (op) &&
1632 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1633 /* TARGET_IS_DS390)) */
1634 (options.model == MODEL_FLAT24) ))
1636 op = operandFromOperand (op);
1641 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1642 if (IS_PTR (type) && op->isaddr && force)
1645 type = copyLinkChain (type);
1647 IC_RESULT (ic) = newiTempOperand (type, 1);
1648 IC_RESULT (ic)->isaddr = 0;
1650 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1654 return IC_RESULT (ic);
1657 /*-----------------------------------------------------------------*/
1658 /* geniCodeCast - changes the value from one type to another */
1659 /*-----------------------------------------------------------------*/
1661 geniCodeCast (sym_link * type, operand * op, bool implicit)
1665 sym_link *opetype = getSpec (optype = operandType (op));
1669 /* one of them has size zero then error */
1670 if (IS_VOID (optype))
1672 werror (E_CAST_ZERO);
1676 /* if the operand is already the desired type then do nothing */
1677 if (compareType (type, optype) == 1)
1680 /* if this is a literal then just change the type & return */
1681 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1682 return operandFromValue (valCastLiteral (type,
1683 operandLitValue (op)));
1685 /* if casting to/from pointers, do some checking */
1686 if (IS_PTR(type)) { // to a pointer
1687 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1688 if (IS_INTEGRAL(optype)) {
1689 // maybe this is NULL, than it's ok.
1690 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1691 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1692 // no way to set the storage
1693 if (IS_LITERAL(optype)) {
1694 werror(E_LITERAL_GENERIC);
1697 werror(E_NONPTR2_GENPTR);
1700 } else if (implicit) {
1701 werror(W_INTEGRAL2PTR_NOCAST);
1706 // shouldn't do that with float, array or structure unless to void
1707 if (!IS_VOID(getSpec(type)) &&
1708 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1709 werror(E_INCOMPAT_TYPES);
1713 } else { // from a pointer to a pointer
1714 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1715 // if not a pointer to a function
1716 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1717 if (implicit) { // if not to generic, they have to match
1718 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1719 werror(E_INCOMPAT_PTYPES);
1726 } else { // to a non pointer
1727 if (IS_PTR(optype)) { // from a pointer
1728 if (implicit) { // sneaky
1729 if (IS_INTEGRAL(type)) {
1730 werror(W_PTR2INTEGRAL_NOCAST);
1732 } else { // shouldn't do that with float, array or structure
1733 werror(E_INCOMPAT_TYPES);
1740 printFromToType (optype, type);
1743 /* if they are the same size create an assignment */
1744 if (getSize (type) == getSize (optype) &&
1745 !IS_BITFIELD (type) &&
1747 !IS_FLOAT (optype) &&
1748 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1749 (!IS_SPEC (type) && !IS_SPEC (optype))))
1752 ic = newiCode ('=', NULL, op);
1753 IC_RESULT (ic) = newiTempOperand (type, 0);
1754 SPIL_LOC (IC_RESULT (ic)) =
1755 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1756 IC_RESULT (ic)->isaddr = 0;
1760 ic = newiCode (CAST, operandFromLink (type),
1761 geniCodeRValue (op, FALSE));
1763 IC_RESULT (ic) = newiTempOperand (type, 0);
1766 /* preserve the storage class & output class */
1767 /* of the original variable */
1768 restype = getSpec (operandType (IC_RESULT (ic)));
1769 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1770 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1773 return IC_RESULT (ic);
1776 /*-----------------------------------------------------------------*/
1777 /* geniCodeLabel - will create a Label */
1778 /*-----------------------------------------------------------------*/
1780 geniCodeLabel (symbol * label)
1784 ic = newiCodeLabelGoto (LABEL, label);
1788 /*-----------------------------------------------------------------*/
1789 /* geniCodeGoto - will create a Goto */
1790 /*-----------------------------------------------------------------*/
1792 geniCodeGoto (symbol * label)
1796 ic = newiCodeLabelGoto (GOTO, label);
1800 /*-----------------------------------------------------------------*/
1801 /* geniCodeMultiply - gen intermediate code for multiplication */
1802 /*-----------------------------------------------------------------*/
1804 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1811 /* if they are both literal then we know the result */
1812 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1813 return operandFromValue (valMult (left->operand.valOperand,
1814 right->operand.valOperand));
1816 if (IS_LITERAL(retype)) {
1817 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1820 resType = usualBinaryConversions (&left, &right);
1822 rtype = operandType (right);
1823 retype = getSpec (rtype);
1824 ltype = operandType (left);
1825 letype = getSpec (ltype);
1829 SPEC_NOUN(getSpec(resType))=V_INT;
1832 /* if the right is a literal & power of 2 */
1833 /* then make it a left shift */
1834 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1835 efficient in most cases than 2 bytes result = 2 bytes << literal
1836 if port has 1 byte muldiv */
1837 if (p2 && !IS_FLOAT (letype) &&
1838 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1839 (port->support.muldiv == 1)))
1841 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1843 /* LEFT_OP need same size for left and result, */
1844 left = geniCodeCast (resType, left, TRUE);
1845 ltype = operandType (left);
1847 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1851 ic = newiCode ('*', left, right); /* normal multiplication */
1852 /* if the size left or right > 1 then support routine */
1853 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1857 IC_RESULT (ic) = newiTempOperand (resType, 1);
1860 return IC_RESULT (ic);
1863 /*-----------------------------------------------------------------*/
1864 /* geniCodeDivision - gen intermediate code for division */
1865 /*-----------------------------------------------------------------*/
1867 geniCodeDivision (operand * left, operand * right)
1872 sym_link *rtype = operandType (right);
1873 sym_link *retype = getSpec (rtype);
1874 sym_link *ltype = operandType (left);
1875 sym_link *letype = getSpec (ltype);
1877 resType = usualBinaryConversions (&left, &right);
1879 /* if the right is a literal & power of 2 */
1880 /* then make it a right shift */
1881 if (IS_LITERAL (retype) &&
1882 !IS_FLOAT (letype) &&
1883 (p2 = powof2 ((unsigned long)
1884 floatFromVal (right->operand.valOperand)))) {
1885 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1889 ic = newiCode ('/', left, right); /* normal division */
1890 /* if the size left or right > 1 then support routine */
1891 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1894 IC_RESULT (ic) = newiTempOperand (resType, 0);
1897 return IC_RESULT (ic);
1899 /*-----------------------------------------------------------------*/
1900 /* geniCodeModulus - gen intermediate code for modulus */
1901 /*-----------------------------------------------------------------*/
1903 geniCodeModulus (operand * left, operand * right)
1909 /* if they are both literal then we know the result */
1910 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1911 return operandFromValue (valMod (left->operand.valOperand,
1912 right->operand.valOperand));
1914 resType = usualBinaryConversions (&left, &right);
1916 /* now they are the same size */
1917 ic = newiCode ('%', left, right);
1919 /* if the size left or right > 1 then support routine */
1920 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1922 IC_RESULT (ic) = newiTempOperand (resType, 0);
1925 return IC_RESULT (ic);
1928 /*-----------------------------------------------------------------*/
1929 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1930 /*-----------------------------------------------------------------*/
1932 geniCodePtrPtrSubtract (operand * left, operand * right)
1938 /* if they are both literals then */
1939 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1941 result = operandFromValue (valMinus (left->operand.valOperand,
1942 right->operand.valOperand));
1946 ic = newiCode ('-', left, right);
1948 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1952 return geniCodeDivision (result,
1953 operandFromLit (getSize (ltype->next)));
1956 /*-----------------------------------------------------------------*/
1957 /* geniCodeSubtract - generates code for subtraction */
1958 /*-----------------------------------------------------------------*/
1960 geniCodeSubtract (operand * left, operand * right)
1967 /* if they both pointers then */
1968 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1969 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1970 return geniCodePtrPtrSubtract (left, right);
1972 /* if they are both literal then we know the result */
1973 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1974 && left->isLiteral && right->isLiteral)
1975 return operandFromValue (valMinus (left->operand.valOperand,
1976 right->operand.valOperand));
1978 /* if left is an array or pointer */
1979 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1981 isarray = left->isaddr;
1982 right = geniCodeMultiply (right,
1983 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1984 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1987 { /* make them the same size */
1988 resType = usualBinaryConversions (&left, &right);
1991 ic = newiCode ('-', left, right);
1993 IC_RESULT (ic) = newiTempOperand (resType, 1);
1994 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1996 /* if left or right is a float */
1997 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2001 return IC_RESULT (ic);
2004 /*-----------------------------------------------------------------*/
2005 /* geniCodeAdd - generates iCode for addition */
2006 /*-----------------------------------------------------------------*/
2008 geniCodeAdd (operand * left, operand * right, int lvl)
2016 /* if left is an array then array access */
2017 if (IS_ARRAY (ltype))
2018 return geniCodeArray (left, right,lvl);
2020 /* if the right side is LITERAL zero */
2021 /* return the left side */
2022 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2025 /* if left is literal zero return right */
2026 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2029 /* if left is a pointer then size */
2032 isarray = left->isaddr;
2033 // there is no need to multiply with 1
2034 if (getSize(ltype->next)!=1) {
2035 size = operandFromLit (getSize (ltype->next));
2036 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2038 resType = copyLinkChain (ltype);
2041 { // make them the same size
2042 resType = usualBinaryConversions (&left, &right);
2045 /* if they are both literals then we know */
2046 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2047 && left->isLiteral && right->isLiteral)
2048 return operandFromValue (valPlus (valFromType (letype),
2049 valFromType (retype)));
2051 ic = newiCode ('+', left, right);
2053 IC_RESULT (ic) = newiTempOperand (resType, 1);
2054 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2056 /* if left or right is a float then support
2058 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2063 return IC_RESULT (ic);
2067 /*-----------------------------------------------------------------*/
2068 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2069 /*-----------------------------------------------------------------*/
2071 aggrToPtr (sym_link * type, bool force)
2077 if (IS_PTR (type) && !force)
2080 etype = getSpec (type);
2084 /* if the output class is generic */
2085 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2086 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2088 /* if the variable was declared a constant */
2089 /* then the pointer points to a constant */
2090 if (IS_CONSTANT (etype))
2091 DCL_PTR_CONST (ptype) = 1;
2093 /* the variable was volatile then pointer to volatile */
2094 if (IS_VOLATILE (etype))
2095 DCL_PTR_VOLATILE (ptype) = 1;
2099 /*-----------------------------------------------------------------*/
2100 /* geniCodeArray2Ptr - array to pointer */
2101 /*-----------------------------------------------------------------*/
2103 geniCodeArray2Ptr (operand * op)
2105 sym_link *optype = operandType (op);
2106 sym_link *opetype = getSpec (optype);
2108 /* set the pointer depending on the storage class */
2109 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2110 DCL_PTR_CONST (optype) = port->mem.code_ro;
2113 /* if the variable was declared a constant */
2114 /* then the pointer points to a constant */
2115 if (IS_CONSTANT (opetype))
2116 DCL_PTR_CONST (optype) = 1;
2118 /* the variable was volatile then pointer to volatile */
2119 if (IS_VOLATILE (opetype))
2120 DCL_PTR_VOLATILE (optype) = 1;
2126 /*-----------------------------------------------------------------*/
2127 /* geniCodeArray - array access */
2128 /*-----------------------------------------------------------------*/
2130 geniCodeArray (operand * left, operand * right,int lvl)
2133 sym_link *ltype = operandType (left);
2137 if (IS_PTR (ltype->next) && left->isaddr)
2139 left = geniCodeRValue (left, FALSE);
2141 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2144 right = geniCodeMultiply (right,
2145 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2147 /* we can check for limits here */
2148 if (isOperandLiteral (right) &&
2151 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2153 werror (E_ARRAY_BOUND);
2154 right = operandFromLit (0);
2157 ic = newiCode ('+', left, right);
2159 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2160 !IS_AGGREGATE (ltype->next) &&
2161 !IS_PTR (ltype->next))
2162 ? ltype : ltype->next), 0);
2164 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2166 return IC_RESULT (ic);
2169 /*-----------------------------------------------------------------*/
2170 /* geniCodeStruct - generates intermediate code for structres */
2171 /*-----------------------------------------------------------------*/
2173 geniCodeStruct (operand * left, operand * right, bool islval)
2176 sym_link *type = operandType (left);
2177 sym_link *etype = getSpec (type);
2179 symbol *element = getStructElement (SPEC_STRUCT (etype),
2180 right->operand.symOperand);
2182 /* add the offset */
2183 ic = newiCode ('+', left, operandFromLit (element->offset));
2185 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2187 /* preserve the storage & output class of the struct */
2188 /* as well as the volatile attribute */
2189 retype = getSpec (operandType (IC_RESULT (ic)));
2190 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2191 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2192 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2194 if (IS_PTR (element->type))
2195 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2197 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2201 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2204 /*-----------------------------------------------------------------*/
2205 /* geniCodePostInc - generate int code for Post increment */
2206 /*-----------------------------------------------------------------*/
2208 geniCodePostInc (operand * op)
2212 sym_link *optype = operandType (op);
2214 operand *rv = (IS_ITEMP (op) ?
2215 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2217 sym_link *rvtype = operandType (rv);
2220 /* if this is not an address we have trouble */
2223 werror (E_LVALUE_REQUIRED, "++");
2227 rOp = newiTempOperand (rvtype, 0);
2228 OP_SYMBOL(rOp)->noSpilLoc = 1;
2231 OP_SYMBOL(rv)->noSpilLoc = 1;
2233 geniCodeAssign (rOp, rv, 0);
2235 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2236 if (IS_FLOAT (rvtype))
2237 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2239 ic = newiCode ('+', rv, operandFromLit (size));
2241 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2244 geniCodeAssign (op, result, 0);
2250 /*-----------------------------------------------------------------*/
2251 /* geniCodePreInc - generate code for preIncrement */
2252 /*-----------------------------------------------------------------*/
2254 geniCodePreInc (operand * op)
2257 sym_link *optype = operandType (op);
2258 operand *rop = (IS_ITEMP (op) ?
2259 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2261 sym_link *roptype = operandType (rop);
2267 werror (E_LVALUE_REQUIRED, "++");
2272 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2273 if (IS_FLOAT (roptype))
2274 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2276 ic = newiCode ('+', rop, operandFromLit (size));
2277 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2281 return geniCodeAssign (op, result, 0);
2284 /*-----------------------------------------------------------------*/
2285 /* geniCodePostDec - generates code for Post decrement */
2286 /*-----------------------------------------------------------------*/
2288 geniCodePostDec (operand * op)
2292 sym_link *optype = operandType (op);
2294 operand *rv = (IS_ITEMP (op) ?
2295 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2297 sym_link *rvtype = operandType (rv);
2300 /* if this is not an address we have trouble */
2303 werror (E_LVALUE_REQUIRED, "--");
2307 rOp = newiTempOperand (rvtype, 0);
2308 OP_SYMBOL(rOp)->noSpilLoc = 1;
2311 OP_SYMBOL(rv)->noSpilLoc = 1;
2313 geniCodeAssign (rOp, rv, 0);
2315 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2316 if (IS_FLOAT (rvtype))
2317 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2319 ic = newiCode ('-', rv, operandFromLit (size));
2321 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2324 geniCodeAssign (op, result, 0);
2330 /*-----------------------------------------------------------------*/
2331 /* geniCodePreDec - generate code for pre decrement */
2332 /*-----------------------------------------------------------------*/
2334 geniCodePreDec (operand * op)
2337 sym_link *optype = operandType (op);
2338 operand *rop = (IS_ITEMP (op) ?
2339 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2341 sym_link *roptype = operandType (rop);
2347 werror (E_LVALUE_REQUIRED, "--");
2352 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2353 if (IS_FLOAT (roptype))
2354 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2356 ic = newiCode ('-', rop, operandFromLit (size));
2357 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2361 return geniCodeAssign (op, result, 0);
2365 /*-----------------------------------------------------------------*/
2366 /* geniCodeBitwise - gen int code for bitWise operators */
2367 /*-----------------------------------------------------------------*/
2369 geniCodeBitwise (operand * left, operand * right,
2370 int oper, sym_link * resType)
2374 left = geniCodeCast (resType, left, TRUE);
2375 right = geniCodeCast (resType, right, TRUE);
2377 ic = newiCode (oper, left, right);
2378 IC_RESULT (ic) = newiTempOperand (resType, 0);
2381 return IC_RESULT (ic);
2384 /*-----------------------------------------------------------------*/
2385 /* geniCodeAddressOf - gens icode for '&' address of operator */
2386 /*-----------------------------------------------------------------*/
2388 geniCodeAddressOf (operand * op)
2392 sym_link *optype = operandType (op);
2393 sym_link *opetype = getSpec (optype);
2395 /* lvalue check already done in decorateType */
2396 /* this must be a lvalue */
2397 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2398 /* werror (E_LVALUE_REQUIRED,"&"); */
2403 p->class = DECLARATOR;
2405 /* set the pointer depending on the storage class */
2406 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2407 DCL_PTR_CONST (p) = port->mem.code_ro;
2409 /* make sure we preserve the const & volatile */
2410 if (IS_CONSTANT (opetype))
2411 DCL_PTR_CONST (p) = 1;
2413 if (IS_VOLATILE (opetype))
2414 DCL_PTR_VOLATILE (p) = 1;
2416 p->next = copyLinkChain (optype);
2418 /* if already a temp */
2421 setOperandType (op, p);
2426 /* other wise make this of the type coming in */
2427 ic = newiCode (ADDRESS_OF, op, NULL);
2428 IC_RESULT (ic) = newiTempOperand (p, 1);
2429 IC_RESULT (ic)->isaddr = 0;
2431 return IC_RESULT (ic);
2433 /*-----------------------------------------------------------------*/
2434 /* setOClass - sets the output class depending on the pointer type */
2435 /*-----------------------------------------------------------------*/
2437 setOClass (sym_link * ptr, sym_link * spec)
2439 switch (DCL_TYPE (ptr))
2442 SPEC_OCLS (spec) = data;
2446 SPEC_OCLS (spec) = generic;
2450 SPEC_OCLS (spec) = xdata;
2454 SPEC_OCLS (spec) = code;
2458 SPEC_OCLS (spec) = idata;
2462 SPEC_OCLS (spec) = xstack;
2466 SPEC_OCLS (spec) = eeprom;
2475 /*-----------------------------------------------------------------*/
2476 /* geniCodeDerefPtr - dereference pointer with '*' */
2477 /*-----------------------------------------------------------------*/
2479 geniCodeDerefPtr (operand * op,int lvl)
2481 sym_link *rtype, *retype;
2482 sym_link *optype = operandType (op);
2484 /* if this is a pointer then generate the rvalue */
2485 if (IS_PTR (optype))
2487 if (IS_TRUE_SYMOP (op))
2490 op = geniCodeRValue (op, TRUE);
2493 op = geniCodeRValue (op, TRUE);
2496 /* now get rid of the pointer part */
2497 if (isLvaluereq(lvl) && IS_ITEMP (op))
2499 retype = getSpec (rtype = copyLinkChain (optype));
2503 retype = getSpec (rtype = copyLinkChain (optype->next));
2506 /* if this is a pointer then outputclass needs 2b updated */
2507 if (IS_PTR (optype))
2508 setOClass (optype, retype);
2510 op->isGptr = IS_GENPTR (optype);
2512 /* if the pointer was declared as a constant */
2513 /* then we cannot allow assignment to the derefed */
2514 if (IS_PTR_CONST (optype))
2515 SPEC_CONST (retype) = 1;
2517 op->isaddr = (IS_PTR (rtype) ||
2518 IS_STRUCT (rtype) ||
2523 if (!isLvaluereq(lvl))
2524 op = geniCodeRValue (op, TRUE);
2526 setOperandType (op, rtype);
2531 /*-----------------------------------------------------------------*/
2532 /* geniCodeUnaryMinus - does a unary minus of the operand */
2533 /*-----------------------------------------------------------------*/
2535 geniCodeUnaryMinus (operand * op)
2538 sym_link *optype = operandType (op);
2540 if (IS_LITERAL (optype))
2541 return operandFromLit (-floatFromVal (op->operand.valOperand));
2543 ic = newiCode (UNARYMINUS, op, NULL);
2544 IC_RESULT (ic) = newiTempOperand (optype, 0);
2546 return IC_RESULT (ic);
2549 /*-----------------------------------------------------------------*/
2550 /* geniCodeLeftShift - gen i code for left shift */
2551 /*-----------------------------------------------------------------*/
2553 geniCodeLeftShift (operand * left, operand * right)
2557 ic = newiCode (LEFT_OP, left, right);
2558 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2560 return IC_RESULT (ic);
2563 /*-----------------------------------------------------------------*/
2564 /* geniCodeRightShift - gen i code for right shift */
2565 /*-----------------------------------------------------------------*/
2567 geniCodeRightShift (operand * left, operand * right)
2571 ic = newiCode (RIGHT_OP, left, right);
2572 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2574 return IC_RESULT (ic);
2577 /*-----------------------------------------------------------------*/
2578 /* geniCodeLogic- logic code */
2579 /*-----------------------------------------------------------------*/
2581 geniCodeLogic (operand * left, operand * right, int op)
2585 sym_link *rtype = operandType (right);
2586 sym_link *ltype = operandType (left);
2588 /* left is integral type and right is literal then
2589 check if the literal value is within bounds */
2590 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2592 checkConstantRange(ltype,
2593 OP_VALUE(right), "compare operation", 1);
2596 ctype = usualBinaryConversions (&left, &right);
2598 ic = newiCode (op, left, right);
2599 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2601 /* if comparing float
2602 and not a '==' || '!=' || '&&' || '||' (these
2604 if (IS_FLOAT(ctype) &&
2612 return IC_RESULT (ic);
2615 /*-----------------------------------------------------------------*/
2616 /* geniCodeUnary - for a a generic unary operation */
2617 /*-----------------------------------------------------------------*/
2619 geniCodeUnary (operand * op, int oper)
2621 iCode *ic = newiCode (oper, op, NULL);
2623 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2625 return IC_RESULT (ic);
2628 /*-----------------------------------------------------------------*/
2629 /* geniCodeConditional - geniCode for '?' ':' operation */
2630 /*-----------------------------------------------------------------*/
2632 geniCodeConditional (ast * tree,int lvl)
2635 symbol *falseLabel = newiTempLabel (NULL);
2636 symbol *exitLabel = newiTempLabel (NULL);
2637 operand *cond = ast2iCode (tree->left,lvl+1);
2638 operand *true, *false, *result;
2640 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2644 true = ast2iCode (tree->right->left,lvl+1);
2646 /* move the value to a new Operand */
2647 result = newiTempOperand (tree->right->ftype, 0);
2648 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2650 /* generate an unconditional goto */
2651 geniCodeGoto (exitLabel);
2653 /* now for the right side */
2654 geniCodeLabel (falseLabel);
2656 false = ast2iCode (tree->right->right,lvl+1);
2657 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2659 /* create the exit label */
2660 geniCodeLabel (exitLabel);
2665 /*-----------------------------------------------------------------*/
2666 /* geniCodeAssign - generate code for assignment */
2667 /*-----------------------------------------------------------------*/
2669 geniCodeAssign (operand * left, operand * right, int nosupdate)
2672 sym_link *ltype = operandType (left);
2673 sym_link *rtype = operandType (right);
2675 if (!left->isaddr && !IS_ITEMP (left))
2677 werror (E_LVALUE_REQUIRED, "assignment");
2681 /* left is integral type and right is literal then
2682 check if the literal value is within bounds */
2683 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2685 checkConstantRange(ltype,
2686 OP_VALUE(right), "= operation", 0);
2689 /* if the left & right type don't exactly match */
2690 /* if pointer set then make sure the check is
2691 done with the type & not the pointer */
2692 /* then cast rights type to left */
2694 /* first check the type for pointer assignement */
2695 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2696 compareType (ltype, rtype) <= 0)
2698 if (compareType (ltype->next, rtype) < 0)
2699 right = geniCodeCast (ltype->next, right, TRUE);
2701 else if (compareType (ltype, rtype) < 0)
2702 right = geniCodeCast (ltype, right, TRUE);
2704 /* if left is a true symbol & ! volatile
2705 create an assignment to temporary for
2706 the right & then assign this temporary
2707 to the symbol this is SSA . isn't it simple
2708 and folks have published mountains of paper on it */
2709 if (IS_TRUE_SYMOP (left) &&
2710 !isOperandVolatile (left, FALSE) &&
2711 isOperandGlobal (left))
2715 if (IS_TRUE_SYMOP (right))
2716 sym = OP_SYMBOL (right);
2717 ic = newiCode ('=', NULL, right);
2718 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2719 SPIL_LOC (right) = sym;
2723 ic = newiCode ('=', NULL, right);
2724 IC_RESULT (ic) = left;
2727 /* if left isgptr flag is set then support
2728 routine will be required */
2732 ic->nosupdate = nosupdate;
2736 /*-----------------------------------------------------------------*/
2737 /* geniCodeSEParms - generate code for side effecting fcalls */
2738 /*-----------------------------------------------------------------*/
2740 geniCodeSEParms (ast * parms,int lvl)
2745 if (parms->type == EX_OP && parms->opval.op == PARAM)
2747 geniCodeSEParms (parms->left,lvl);
2748 geniCodeSEParms (parms->right,lvl);
2752 /* hack don't like this but too lazy to think of
2754 if (IS_ADDRESS_OF_OP (parms))
2755 parms->left->lvalue = 1;
2757 if (IS_CAST_OP (parms) &&
2758 IS_PTR (parms->ftype) &&
2759 IS_ADDRESS_OF_OP (parms->right))
2760 parms->right->left->lvalue = 1;
2762 parms->opval.oprnd =
2763 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2765 parms->type = EX_OPERAND;
2768 /*-----------------------------------------------------------------*/
2769 /* geniCodeParms - generates parameters */
2770 /*-----------------------------------------------------------------*/
2772 geniCodeParms (ast * parms, value *argVals, int *stack,
2773 sym_link * fetype, symbol * func,int lvl)
2781 if (argVals==NULL) {
2783 argVals=FUNC_ARGS(func->type);
2786 /* if this is a param node then do the left & right */
2787 if (parms->type == EX_OP && parms->opval.op == PARAM)
2789 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2790 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2794 /* get the parameter value */
2795 if (parms->type == EX_OPERAND)
2796 pval = parms->opval.oprnd;
2799 /* maybe this else should go away ?? */
2800 /* hack don't like this but too lazy to think of
2802 if (IS_ADDRESS_OF_OP (parms))
2803 parms->left->lvalue = 1;
2805 if (IS_CAST_OP (parms) &&
2806 IS_PTR (parms->ftype) &&
2807 IS_ADDRESS_OF_OP (parms->right))
2808 parms->right->left->lvalue = 1;
2810 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2813 /* if register parm then make it a send */
2814 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2815 IFFUNC_ISBUILTIN(func->type))
2817 ic = newiCode (SEND, pval, NULL);
2818 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2823 /* now decide whether to push or assign */
2824 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2828 operand *top = operandFromSymbol (argVals->sym);
2829 /* clear useDef and other bitVectors */
2830 OP_USES (top) = OP_DEFS (top) = OP_SYMBOL(top)->clashes = NULL;
2831 geniCodeAssign (top, pval, 1);
2835 sym_link *p = operandType (pval);
2837 ic = newiCode (IPUSH, pval, NULL);
2839 /* update the stack adjustment */
2840 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2845 argVals=argVals->next;
2849 /*-----------------------------------------------------------------*/
2850 /* geniCodeCall - generates temp code for calling */
2851 /*-----------------------------------------------------------------*/
2853 geniCodeCall (operand * left, ast * parms,int lvl)
2857 sym_link *type, *etype;
2860 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2861 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2862 werror (E_FUNCTION_EXPECTED);
2866 /* take care of parameters with side-effecting
2867 function calls in them, this is required to take care
2868 of overlaying function parameters */
2869 geniCodeSEParms (parms,lvl);
2871 /* first the parameters */
2872 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2874 /* now call : if symbol then pcall */
2875 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
2876 ic = newiCode (PCALL, left, NULL);
2878 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);
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 ();