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,
132 char message[132]="";
137 max = pow ((double)2.0, (double)bitsForType(ltype));
139 if (SPEC_LONG(val->type)) {
140 if (SPEC_USIGN(val->type)) {
141 v=SPEC_CVAL(val->type).v_ulong;
143 v=SPEC_CVAL(val->type).v_long;
146 if (SPEC_USIGN(val->type)) {
147 v=SPEC_CVAL(val->type).v_uint;
149 v=SPEC_CVAL(val->type).v_int;
155 // this could be a good idea
156 if (options.pedantic)
160 if (SPEC_NOUN(ltype)==FLOAT) {
165 if (!SPEC_USIGN(val->type) && v<0) {
167 if (SPEC_USIGN(ltype) && (pedantic>1)) {
173 // if very pedantic: "char c=200" is not allowed
174 if (pedantic>1 && !SPEC_USIGN(ltype)) {
175 max = max/2 + negative;
182 #if 0 // temporary disabled, leaving the warning as a reminder
184 sprintf (message, "for %s %s in %s",
185 SPEC_USIGN(ltype) ? "unsigned" : "signed",
186 nounName(ltype), msg);
187 werror (W_CONST_RANGE, message);
195 /*-----------------------------------------------------------------*/
196 /* operandName - returns the name of the operand */
197 /*-----------------------------------------------------------------*/
199 printOperand (operand * op, FILE * file)
216 opetype = getSpec (operandType (op));
217 if (SPEC_NOUN (opetype) == V_FLOAT)
218 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
220 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
221 printTypeChain (operandType (op), file);
228 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}" , */
229 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
231 OP_LIVEFROM (op), OP_LIVETO (op),
232 OP_SYMBOL (op)->stack,
233 op->isaddr, OP_SYMBOL (op)->isreqv, 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 an array or 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);
2880 type = copyLinkChain (operandType (left)->next);
2881 etype = getSpec (type);
2882 SPEC_EXTR (etype) = 0;
2883 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2887 /* stack adjustment after call */
2888 ic->parmBytes = stack;
2893 /*-----------------------------------------------------------------*/
2894 /* geniCodeReceive - generate intermediate code for "receive" */
2895 /*-----------------------------------------------------------------*/
2897 geniCodeReceive (value * args)
2899 /* for all arguments that are passed in registers */
2903 if (IS_REGPARM (args->etype))
2905 operand *opr = operandFromValue (args);
2907 symbol *sym = OP_SYMBOL (opr);
2910 /* we will use it after all optimizations
2911 and before liveRange calculation */
2912 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2915 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2916 options.stackAuto == 0 &&
2917 /* !TARGET_IS_DS390) */
2918 (!(options.model == MODEL_FLAT24)) )
2923 opl = newiTempOperand (args->type, 0);
2925 sym->reqv->key = sym->key;
2926 OP_SYMBOL (sym->reqv)->key = sym->key;
2927 OP_SYMBOL (sym->reqv)->isreqv = 1;
2928 OP_SYMBOL (sym->reqv)->islocal = 0;
2929 SPIL_LOC (sym->reqv) = sym;
2933 ic = newiCode (RECEIVE, NULL, NULL);
2934 currFunc->recvSize = getSize (sym->etype);
2935 IC_RESULT (ic) = opr;
2943 /*-----------------------------------------------------------------*/
2944 /* geniCodeFunctionBody - create the function body */
2945 /*-----------------------------------------------------------------*/
2947 geniCodeFunctionBody (ast * tree,int lvl)
2954 /* reset the auto generation */
2960 func = ast2iCode (tree->left,lvl+1);
2961 fetype = getSpec (operandType (func));
2963 savelineno = lineno;
2964 lineno = OP_SYMBOL (func)->lineDef;
2965 /* create an entry label */
2966 geniCodeLabel (entryLabel);
2967 lineno = savelineno;
2969 /* create a proc icode */
2970 ic = newiCode (FUNCTION, func, NULL);
2971 ic->lineno = OP_SYMBOL (func)->lineDef;
2975 /* for all parameters that are passed
2976 on registers add a "receive" */
2977 geniCodeReceive (tree->values.args);
2979 /* generate code for the body */
2980 ast2iCode (tree->right,lvl+1);
2982 /* create a label for return */
2983 geniCodeLabel (returnLabel);
2985 /* now generate the end proc */
2986 ic = newiCode (ENDFUNCTION, func, NULL);
2991 /*-----------------------------------------------------------------*/
2992 /* geniCodeReturn - gen icode for 'return' statement */
2993 /*-----------------------------------------------------------------*/
2995 geniCodeReturn (operand * op)
2999 /* if the operand is present force an rvalue */
3001 op = geniCodeRValue (op, FALSE);
3003 ic = newiCode (RETURN, op, NULL);
3007 /*-----------------------------------------------------------------*/
3008 /* geniCodeIfx - generates code for extended if statement */
3009 /*-----------------------------------------------------------------*/
3011 geniCodeIfx (ast * tree,int lvl)
3014 operand *condition = ast2iCode (tree->left,lvl+1);
3017 /* if condition is null then exit */
3021 condition = geniCodeRValue (condition, FALSE);
3023 cetype = getSpec (operandType (condition));
3024 /* if the condition is a literal */
3025 if (IS_LITERAL (cetype))
3027 if (floatFromVal (condition->operand.valOperand))
3029 if (tree->trueLabel)
3030 geniCodeGoto (tree->trueLabel);
3036 if (tree->falseLabel)
3037 geniCodeGoto (tree->falseLabel);
3044 if (tree->trueLabel)
3046 ic = newiCodeCondition (condition,
3051 if (tree->falseLabel)
3052 geniCodeGoto (tree->falseLabel);
3056 ic = newiCodeCondition (condition,
3063 ast2iCode (tree->right,lvl+1);
3066 /*-----------------------------------------------------------------*/
3067 /* geniCodeJumpTable - tries to create a jump table for switch */
3068 /*-----------------------------------------------------------------*/
3070 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3072 int min = 0, max = 0, t, cnt = 0;
3079 if (!tree || !caseVals)
3082 /* the criteria for creating a jump table is */
3083 /* all integer numbers between the maximum & minimum must */
3084 /* be present , the maximum value should not exceed 255 */
3085 min = max = (int) floatFromVal (vch = caseVals);
3086 sprintf (buffer, "_case_%d_%d",
3087 tree->values.switchVals.swNum,
3089 addSet (&labels, newiTempLabel (buffer));
3091 /* if there is only one case value then no need */
3092 if (!(vch = vch->next))
3097 if (((t = (int) floatFromVal (vch)) - max) != 1)
3099 sprintf (buffer, "_case_%d_%d",
3100 tree->values.switchVals.swNum,
3102 addSet (&labels, newiTempLabel (buffer));
3108 /* if the number of case statements <= 2 then */
3109 /* it is not economical to create the jump table */
3110 /* since two compares are needed for boundary conditions */
3111 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3114 if (tree->values.switchVals.swDefault)
3115 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3117 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3119 falseLabel = newiTempLabel (buffer);
3121 /* so we can create a jumptable */
3122 /* first we rule out the boundary conditions */
3123 /* if only optimization says so */
3124 if (!optimize.noJTabBoundary)
3126 sym_link *cetype = getSpec (operandType (cond));
3127 /* no need to check the lower bound if
3128 the condition is unsigned & minimum value is zero */
3129 if (!(min == 0 && SPEC_USIGN (cetype)))
3131 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3132 ic = newiCodeCondition (boundary, falseLabel, NULL);
3136 /* now for upper bounds */
3137 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3138 ic = newiCodeCondition (boundary, falseLabel, NULL);
3142 /* if the min is not zero then we no make it zero */
3145 cond = geniCodeSubtract (cond, operandFromLit (min));
3146 setOperandType (cond, UCHARTYPE);
3149 /* now create the jumptable */
3150 ic = newiCode (JUMPTABLE, NULL, NULL);
3151 IC_JTCOND (ic) = cond;
3152 IC_JTLABELS (ic) = labels;
3157 /*-----------------------------------------------------------------*/
3158 /* geniCodeSwitch - changes a switch to a if statement */
3159 /*-----------------------------------------------------------------*/
3161 geniCodeSwitch (ast * tree,int lvl)
3164 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3165 value *caseVals = tree->values.switchVals.swVals;
3166 symbol *trueLabel, *falseLabel;
3168 /* if we can make this a jump table */
3169 if (geniCodeJumpTable (cond, caseVals, tree))
3170 goto jumpTable; /* no need for the comparison */
3172 /* for the cases defined do */
3176 operand *compare = geniCodeLogic (cond,
3177 operandFromValue (caseVals),
3180 sprintf (buffer, "_case_%d_%d",
3181 tree->values.switchVals.swNum,
3182 (int) floatFromVal (caseVals));
3183 trueLabel = newiTempLabel (buffer);
3185 ic = newiCodeCondition (compare, trueLabel, NULL);
3187 caseVals = caseVals->next;
3192 /* if default is present then goto break else break */
3193 if (tree->values.switchVals.swDefault)
3194 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3196 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3198 falseLabel = newiTempLabel (buffer);
3199 geniCodeGoto (falseLabel);
3202 ast2iCode (tree->right,lvl+1);
3205 /*-----------------------------------------------------------------*/
3206 /* geniCodeInline - intermediate code for inline assembler */
3207 /*-----------------------------------------------------------------*/
3209 geniCodeInline (ast * tree)
3213 ic = newiCode (INLINEASM, NULL, NULL);
3214 IC_INLINE (ic) = tree->values.inlineasm;
3218 /*-----------------------------------------------------------------*/
3219 /* geniCodeArrayInit - intermediate code for array initializer */
3220 /*-----------------------------------------------------------------*/
3222 geniCodeArrayInit (ast * tree, operand *array)
3226 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3227 ic = newiCode (ARRAYINIT, array, NULL);
3228 IC_ARRAYILIST (ic) = tree->values.constlist;
3230 operand *left=newOperand(), *right=newOperand();
3231 left->type=right->type=SYMBOL;
3232 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3233 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3234 ic = newiCode (ARRAYINIT, left, right);
3239 /*-----------------------------------------------------------------*/
3240 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3241 /* particular case. Ie : assigning or dereferencing array or ptr */
3242 /*-----------------------------------------------------------------*/
3243 set * lvaluereqSet = NULL;
3244 typedef struct lvalItem
3251 /*-----------------------------------------------------------------*/
3252 /* addLvaluereq - add a flag for lvalreq for current ast level */
3253 /*-----------------------------------------------------------------*/
3254 void addLvaluereq(int lvl)
3256 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3259 addSetHead(&lvaluereqSet,lpItem);
3262 /*-----------------------------------------------------------------*/
3263 /* delLvaluereq - del a flag for lvalreq for current ast level */
3264 /*-----------------------------------------------------------------*/
3268 lpItem = getSet(&lvaluereqSet);
3269 if(lpItem) Safe_free(lpItem);
3271 /*-----------------------------------------------------------------*/
3272 /* clearLvaluereq - clear lvalreq flag */
3273 /*-----------------------------------------------------------------*/
3274 void clearLvaluereq()
3277 lpItem = peekSet(lvaluereqSet);
3278 if(lpItem) lpItem->req = 0;
3280 /*-----------------------------------------------------------------*/
3281 /* getLvaluereq - get the last lvalreq level */
3282 /*-----------------------------------------------------------------*/
3283 int getLvaluereqLvl()
3286 lpItem = peekSet(lvaluereqSet);
3287 if(lpItem) return lpItem->lvl;
3290 /*-----------------------------------------------------------------*/
3291 /* isLvaluereq - is lvalreq valid for this level ? */
3292 /*-----------------------------------------------------------------*/
3293 int isLvaluereq(int lvl)
3296 lpItem = peekSet(lvaluereqSet);
3297 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3301 /*-----------------------------------------------------------------*/
3302 /* ast2iCode - creates an icodeList from an ast */
3303 /*-----------------------------------------------------------------*/
3305 ast2iCode (ast * tree,int lvl)
3307 operand *left = NULL;
3308 operand *right = NULL;
3311 /* set the global variables for filename & line number */
3313 filename = tree->filename;
3315 lineno = tree->lineno;
3317 block = tree->block;
3319 scopeLevel = tree->level;
3321 if (tree->type == EX_VALUE)
3322 return operandFromValue (tree->opval.val);
3324 if (tree->type == EX_LINK)
3325 return operandFromLink (tree->opval.lnk);
3327 /* if we find a nullop */
3328 if (tree->type == EX_OP &&
3329 (tree->opval.op == NULLOP ||
3330 tree->opval.op == BLOCK))
3332 ast2iCode (tree->left,lvl+1);
3333 ast2iCode (tree->right,lvl+1);
3337 /* special cases for not evaluating */
3338 if (tree->opval.op != ':' &&
3339 tree->opval.op != '?' &&
3340 tree->opval.op != CALL &&
3341 tree->opval.op != IFX &&
3342 tree->opval.op != LABEL &&
3343 tree->opval.op != GOTO &&
3344 tree->opval.op != SWITCH &&
3345 tree->opval.op != FUNCTION &&
3346 tree->opval.op != INLINEASM)
3349 if (IS_ASSIGN_OP (tree->opval.op) ||
3350 IS_DEREF_OP (tree) ||
3351 (tree->opval.op == '&' && !tree->right) ||
3352 tree->opval.op == PTR_OP)
3355 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3356 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3359 left = operandFromAst (tree->left,lvl);
3361 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3362 left = geniCodeRValue (left, TRUE);
3366 left = operandFromAst (tree->left,lvl);
3368 if (tree->opval.op == INC_OP ||
3369 tree->opval.op == DEC_OP)
3372 right = operandFromAst (tree->right,lvl);
3377 right = operandFromAst (tree->right,lvl);
3381 /* now depending on the type of operand */
3382 /* this will be a biggy */
3383 switch (tree->opval.op)
3386 case '[': /* array operation */
3388 //sym_link *ltype = operandType (left);
3389 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3390 left = geniCodeRValue (left, FALSE);
3391 right = geniCodeRValue (right, TRUE);
3394 return geniCodeArray (left, right,lvl);
3396 case '.': /* structure dereference */
3397 if (IS_PTR (operandType (left)))
3398 left = geniCodeRValue (left, TRUE);
3400 left = geniCodeRValue (left, FALSE);
3402 return geniCodeStruct (left, right, tree->lvalue);
3404 case PTR_OP: /* structure pointer dereference */
3407 pType = operandType (left);
3408 left = geniCodeRValue (left, TRUE);
3410 setOClass (pType, getSpec (operandType (left)));
3413 return geniCodeStruct (left, right, tree->lvalue);
3415 case INC_OP: /* increment operator */
3417 return geniCodePostInc (left);
3419 return geniCodePreInc (right);
3421 case DEC_OP: /* decrement operator */
3423 return geniCodePostDec (left);
3425 return geniCodePreDec (right);
3427 case '&': /* bitwise and or address of operator */
3429 { /* this is a bitwise operator */
3430 left = geniCodeRValue (left, FALSE);
3431 right = geniCodeRValue (right, FALSE);
3432 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3435 return geniCodeAddressOf (left);
3437 case '|': /* bitwise or & xor */
3439 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3440 geniCodeRValue (right, FALSE),
3445 return geniCodeDivision (geniCodeRValue (left, FALSE),
3446 geniCodeRValue (right, FALSE));
3449 return geniCodeModulus (geniCodeRValue (left, FALSE),
3450 geniCodeRValue (right, FALSE));
3453 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3454 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3456 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3460 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3461 geniCodeRValue (right, FALSE));
3463 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3467 return geniCodeAdd (geniCodeRValue (left, FALSE),
3468 geniCodeRValue (right, FALSE),lvl);
3470 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3473 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3474 geniCodeRValue (right, FALSE));
3477 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3478 geniCodeRValue (right, FALSE));
3480 return geniCodeCast (operandType (left),
3481 geniCodeRValue (right, FALSE), FALSE);
3487 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3491 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3492 setOperandType (op, UCHARTYPE);
3503 return geniCodeLogic (geniCodeRValue (left, FALSE),
3504 geniCodeRValue (right, FALSE),
3507 return geniCodeConditional (tree,lvl);
3510 return operandFromLit (getSize (tree->right->ftype));
3514 sym_link *rtype = operandType (right);
3515 sym_link *ltype = operandType (left);
3516 if (IS_PTR (rtype) && IS_ITEMP (right)
3517 && right->isaddr && compareType (rtype->next, ltype) == 1)
3518 right = geniCodeRValue (right, TRUE);
3520 right = geniCodeRValue (right, FALSE);
3522 geniCodeAssign (left, right, 0);
3527 geniCodeAssign (left,
3528 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3530 geniCodeRValue (right, FALSE),FALSE), 0);
3534 geniCodeAssign (left,
3535 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3537 geniCodeRValue (right, FALSE)), 0);
3540 geniCodeAssign (left,
3541 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3543 geniCodeRValue (right, FALSE)), 0);
3546 sym_link *rtype = operandType (right);
3547 sym_link *ltype = operandType (left);
3548 if (IS_PTR (rtype) && IS_ITEMP (right)
3549 && right->isaddr && compareType (rtype->next, ltype) == 1)
3550 right = geniCodeRValue (right, TRUE);
3552 right = geniCodeRValue (right, FALSE);
3555 return geniCodeAssign (left,
3556 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3562 sym_link *rtype = operandType (right);
3563 sym_link *ltype = operandType (left);
3564 if (IS_PTR (rtype) && IS_ITEMP (right)
3565 && right->isaddr && compareType (rtype->next, ltype) == 1)
3567 right = geniCodeRValue (right, TRUE);
3571 right = geniCodeRValue (right, FALSE);
3574 geniCodeAssign (left,
3575 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3581 geniCodeAssign (left,
3582 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3584 geniCodeRValue (right, FALSE)), 0);
3587 geniCodeAssign (left,
3588 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3590 geniCodeRValue (right, FALSE)), 0);
3593 geniCodeAssign (left,
3594 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3596 geniCodeRValue (right, FALSE),
3598 operandType (left)), 0);
3601 geniCodeAssign (left,
3602 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3604 geniCodeRValue (right, FALSE),
3606 operandType (left)), 0);
3609 geniCodeAssign (left,
3610 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3612 geniCodeRValue (right, FALSE),
3614 operandType (left)), 0);
3616 return geniCodeRValue (right, FALSE);
3619 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3622 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3623 return ast2iCode (tree->right,lvl+1);
3626 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3627 return ast2iCode (tree->right,lvl+1);
3630 geniCodeFunctionBody (tree,lvl);
3634 geniCodeReturn (right);
3638 geniCodeIfx (tree,lvl);
3642 geniCodeSwitch (tree,lvl);
3646 geniCodeInline (tree);
3650 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3657 /*-----------------------------------------------------------------*/
3658 /* reverseICChain - gets from the list and creates a linkedlist */
3659 /*-----------------------------------------------------------------*/
3666 while ((loop = getSet (&iCodeChain)))
3678 /*-----------------------------------------------------------------*/
3679 /* iCodeFromAst - given an ast will convert it to iCode */
3680 /*-----------------------------------------------------------------*/
3682 iCodeFromAst (ast * tree)
3684 returnLabel = newiTempLabel ("_return");
3685 entryLabel = newiTempLabel ("_entry");
3687 return reverseiCChain ();