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 // this makes it more easy to catch bugs
119 struct bitVect *OP_DEFS(struct operand *op) {
120 wassert (IS_SYMOP(op));
121 return OP_SYMBOL(op)->defs;
123 struct bitVect *OP_DEFS_SET(struct operand *op, struct bitVect *bv) {
124 wassert (IS_SYMOP(op));
125 OP_SYMBOL(op)->defs=bv;
128 struct bitVect *OP_USES(struct operand *op) {
129 wassert (IS_SYMOP(op));
130 return OP_SYMBOL(op)->uses;
132 struct bitVect *OP_USES_SET(struct operand *op, struct bitVect *bv) {
133 wassert (IS_SYMOP(op));
134 OP_SYMBOL(op)->uses=bv;
138 /*-----------------------------------------------------------------*/
139 /* checkConstantRange: check a constant against the type */
140 /*-----------------------------------------------------------------*/
142 /* pedantic=0: allmost anything is allowed as long as the absolute
143 value is within the bit range of the type, and -1 is treated as
144 0xf..f for unsigned types (e.g. in assign)
145 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
146 pedantic>1: "char c=200" is not allowed (evaluates to -56)
149 void checkConstantRange(sym_link *ltype, value *val, char *msg,
156 max = pow ((double)2.0, (double)bitsForType(ltype));
158 if (SPEC_LONG(val->type)) {
159 if (SPEC_USIGN(val->type)) {
160 v=SPEC_CVAL(val->type).v_ulong;
162 v=SPEC_CVAL(val->type).v_long;
165 if (SPEC_USIGN(val->type)) {
166 v=SPEC_CVAL(val->type).v_uint;
168 v=SPEC_CVAL(val->type).v_int;
174 // this could be a good idea
175 if (options.pedantic)
179 if (SPEC_NOUN(ltype)==FLOAT) {
184 if (!SPEC_USIGN(val->type) && v<0) {
186 if (SPEC_USIGN(ltype) && (pedantic>1)) {
192 // if very pedantic: "char c=200" is not allowed
193 if (pedantic>1 && !SPEC_USIGN(ltype)) {
194 max = max/2 + negative;
201 #if 0 // temporary disabled, leaving the warning as a reminder
203 SNPRINTF (message, sizeof(message), "for %s %s in %s",
204 SPEC_USIGN(ltype) ? "unsigned" : "signed",
205 nounName(ltype), msg);
206 werror (W_CONST_RANGE, message);
214 /*-----------------------------------------------------------------*/
215 /* operandName - returns the name of the operand */
216 /*-----------------------------------------------------------------*/
218 printOperand (operand * op, FILE * file)
235 opetype = getSpec (operandType (op));
236 if (SPEC_NOUN (opetype) == V_FLOAT)
237 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
239 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
240 printTypeChain (operandType (op), file);
247 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
248 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
250 OP_LIVEFROM (op), OP_LIVETO (op),
251 OP_SYMBOL (op)->stack,
252 op->isaddr, OP_SYMBOL (op)->isreqv,
253 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
254 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
258 printTypeChain (operandType (op), file);
259 if (SPIL_LOC (op) && IS_ITEMP (op))
260 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
265 /* if assigned to registers */
266 if (OP_SYMBOL (op)->nRegs)
268 if (OP_SYMBOL (op)->isspilt)
270 if (!OP_SYMBOL (op)->remat)
271 if (OP_SYMBOL (op)->usl.spillLoc)
272 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
273 OP_SYMBOL (op)->usl.spillLoc->rname :
274 OP_SYMBOL (op)->usl.spillLoc->name));
276 fprintf (file, "[err]");
278 fprintf (file, "[remat]");
284 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
285 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
290 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
291 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
292 /* if assigned to registers */
293 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
297 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
298 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
299 OP_SYMBOL (op)->regs[i]->name :
308 printTypeChain (op->operand.typeOperand, file);
314 fprintf (file, "\n");
319 /*-----------------------------------------------------------------*/
320 /* print functions */
321 /*-----------------------------------------------------------------*/
322 PRINTFUNC (picGetValueAtAddr)
325 printOperand (IC_RESULT (ic), of);
328 printOperand (IC_LEFT (ic), of);
334 PRINTFUNC (picSetValueAtAddr)
338 printOperand (IC_LEFT (ic), of);
339 fprintf (of, "] = ");
340 printOperand (IC_RIGHT (ic), of);
344 PRINTFUNC (picAddrOf)
347 printOperand (IC_RESULT (ic), of);
348 if (IS_ITEMP (IC_LEFT (ic)))
351 fprintf (of, " = &[");
352 printOperand (IC_LEFT (ic), of);
355 if (IS_ITEMP (IC_LEFT (ic)))
356 fprintf (of, " offsetAdd ");
359 printOperand (IC_RIGHT (ic), of);
361 if (IS_ITEMP (IC_LEFT (ic)))
367 PRINTFUNC (picJumpTable)
372 fprintf (of, "%s\t", s);
373 printOperand (IC_JTCOND (ic), of);
375 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
376 sym = setNextItem (IC_JTLABELS (ic)))
377 fprintf (of, "\t\t\t%s\n", sym->name);
380 PRINTFUNC (picGeneric)
383 printOperand (IC_RESULT (ic), of);
385 printOperand (IC_LEFT (ic), of);
386 fprintf (of, " %s ", s);
387 printOperand (IC_RIGHT (ic), of);
391 PRINTFUNC (picGenericOne)
396 printOperand (IC_RESULT (ic), of);
402 fprintf (of, "%s ", s);
403 printOperand (IC_LEFT (ic), of);
406 if (!IC_RESULT (ic) && !IC_LEFT (ic))
409 if (ic->op == SEND || ic->op == RECEIVE) {
410 fprintf(of,"{argreg = %d}",ic->argreg);
418 printOperand (IC_RESULT (ic), of);
420 printOperand (IC_LEFT (ic), of);
421 printOperand (IC_RIGHT (ic), of);
426 PRINTFUNC (picAssign)
430 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
433 printOperand (IC_RESULT (ic), of);
435 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
438 fprintf (of, " %s ", s);
439 printOperand (IC_RIGHT (ic), of);
446 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
452 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
459 printOperand (IC_COND (ic), of);
462 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
465 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
467 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
471 PRINTFUNC (picInline)
473 fprintf (of, "%s", IC_INLINE (ic));
476 PRINTFUNC (picReceive)
478 printOperand (IC_RESULT (ic), of);
479 fprintf (of, " = %s ", s);
480 printOperand (IC_LEFT (ic), of);
484 /*-----------------------------------------------------------------*/
485 /* piCode - prints one iCode */
486 /*-----------------------------------------------------------------*/
488 piCode (void *item, FILE * of)
496 icTab = getTableEntry (ic->op);
497 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
498 ic->filename, ic->lineno,
499 ic->seq, ic->key, ic->depth, ic->supportRtn);
500 icTab->iCodePrint (of, ic, icTab->printName);
506 printiCChain(ic,stdout);
508 /*-----------------------------------------------------------------*/
509 /* printiCChain - prints intermediate code for humans */
510 /*-----------------------------------------------------------------*/
512 printiCChain (iCode * icChain, FILE * of)
519 for (loop = icChain; loop; loop = loop->next)
521 if ((icTab = getTableEntry (loop->op)))
523 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
524 loop->filename, loop->lineno,
525 loop->seq, loop->key, loop->depth, loop->supportRtn);
527 icTab->iCodePrint (of, loop, icTab->printName);
533 /*-----------------------------------------------------------------*/
534 /* newOperand - allocate, init & return a new iCode */
535 /*-----------------------------------------------------------------*/
541 op = Safe_alloc ( sizeof (operand));
547 /*-----------------------------------------------------------------*/
548 /* newiCode - create and return a new iCode entry initialised */
549 /*-----------------------------------------------------------------*/
551 newiCode (int op, operand * left, operand * right)
555 ic = Safe_alloc ( sizeof (iCode));
558 ic->filename = filename;
560 ic->level = scopeLevel;
562 ic->key = iCodeKey++;
564 IC_RIGHT (ic) = right;
569 /*-----------------------------------------------------------------*/
570 /* newiCode for conditional statements */
571 /*-----------------------------------------------------------------*/
573 newiCodeCondition (operand * condition,
579 if (IS_VOID(operandType(condition))) {
580 werror(E_VOID_VALUE_USED);
583 ic = newiCode (IFX, NULL, NULL);
584 IC_COND (ic) = condition;
585 IC_TRUE (ic) = trueLabel;
586 IC_FALSE (ic) = falseLabel;
590 /*-----------------------------------------------------------------*/
591 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
592 /*-----------------------------------------------------------------*/
594 newiCodeLabelGoto (int op, symbol * label)
598 ic = newiCode (op, NULL, NULL);
600 ic->argLabel.label = label;
602 IC_RIGHT (ic) = NULL;
603 IC_RESULT (ic) = NULL;
607 /*-----------------------------------------------------------------*/
608 /* newiTemp - allocate & return a newItemp Variable */
609 /*-----------------------------------------------------------------*/
617 SNPRINTF (buffer, sizeof(buffer), "%s", s);
621 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
624 itmp = newSymbol (buffer, 1);
625 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
631 /*-----------------------------------------------------------------*/
632 /* newiTempLabel - creates a temp variable label */
633 /*-----------------------------------------------------------------*/
635 newiTempLabel (char *s)
639 /* check if this alredy exists */
640 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
645 itmplbl = newSymbol (s, 1);
649 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
650 itmplbl = newSymbol (buffer, 1);
655 itmplbl->key = labelKey++;
656 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
660 /*-----------------------------------------------------------------*/
661 /* newiTempPreheaderLabel - creates a new preheader label */
662 /*-----------------------------------------------------------------*/
664 newiTempPreheaderLabel ()
668 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
669 itmplbl = newSymbol (buffer, 1);
673 itmplbl->key = labelKey++;
674 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
679 /*-----------------------------------------------------------------*/
680 /* initiCode - initialises some iCode related stuff */
681 /*-----------------------------------------------------------------*/
688 /*-----------------------------------------------------------------*/
689 /* copyiCode - make a copy of the iCode given */
690 /*-----------------------------------------------------------------*/
692 copyiCode (iCode * ic)
694 iCode *nic = newiCode (ic->op, NULL, NULL);
696 nic->lineno = ic->lineno;
697 nic->filename = ic->filename;
698 nic->block = ic->block;
699 nic->level = ic->level;
700 nic->parmBytes = ic->parmBytes;
702 /* deal with the special cases first */
706 IC_COND (nic) = operandFromOperand (IC_COND (ic));
707 IC_TRUE (nic) = IC_TRUE (ic);
708 IC_FALSE (nic) = IC_FALSE (ic);
712 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
713 IC_JTLABELS (nic) = IC_JTLABELS (ic);
718 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
719 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
723 IC_INLINE (nic) = IC_INLINE (ic);
727 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
731 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
732 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
733 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
739 /*-----------------------------------------------------------------*/
740 /* getTableEntry - gets the table entry for the given operator */
741 /*-----------------------------------------------------------------*/
743 getTableEntry (int oper)
747 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
748 if (oper == codeTable[i].icode)
749 return &codeTable[i];
754 /*-----------------------------------------------------------------*/
755 /* newiTempOperand - new intermediate temp operand */
756 /*-----------------------------------------------------------------*/
758 newiTempOperand (sym_link * type, char throwType)
761 operand *op = newOperand ();
765 itmp = newiTemp (NULL);
767 etype = getSpec (type);
769 if (IS_LITERAL (etype))
772 /* copy the type information */
774 itmp->etype = getSpec (itmp->type = (throwType ? type :
775 copyLinkChain (type)));
776 if (IS_LITERAL (itmp->etype))
778 SPEC_SCLS (itmp->etype) = S_REGISTER;
779 SPEC_OCLS (itmp->etype) = reg;
782 op->operand.symOperand = itmp;
783 op->key = itmp->key = ++operandKey;
787 /*-----------------------------------------------------------------*/
788 /* operandType - returns the type chain for an operand */
789 /*-----------------------------------------------------------------*/
791 operandType (operand * op)
793 /* depending on type of operand */
798 return op->operand.valOperand->type;
801 return op->operand.symOperand->type;
804 return op->operand.typeOperand;
806 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
807 " operand type not known ");
808 assert (0); /* should never come here */
809 /* Just to keep the compiler happy */
810 return (sym_link *) 0;
814 /*-----------------------------------------------------------------*/
815 /* isParamterToCall - will return 1 if op is a parameter to args */
816 /*-----------------------------------------------------------------*/
818 isParameterToCall (value * args, operand * op)
825 isSymbolEqual (op->operand.symOperand, tval->sym))
832 /*-----------------------------------------------------------------*/
833 /* isOperandGlobal - return 1 if operand is a global variable */
834 /*-----------------------------------------------------------------*/
836 isOperandGlobal (operand * op)
844 if (op->type == SYMBOL &&
845 (op->operand.symOperand->level == 0 ||
846 IS_STATIC (op->operand.symOperand->etype) ||
847 IS_EXTERN (op->operand.symOperand->etype))
854 /*-----------------------------------------------------------------*/
855 /* isOperandVolatile - return 1 if the operand is volatile */
856 /*-----------------------------------------------------------------*/
858 isOperandVolatile (operand * op, bool chkTemp)
863 if (IS_ITEMP (op) && !chkTemp)
866 opetype = getSpec (optype = operandType (op));
868 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
871 if (IS_VOLATILE (opetype))
876 /*-----------------------------------------------------------------*/
877 /* isOperandLiteral - returns 1 if an operand contains a literal */
878 /*-----------------------------------------------------------------*/
880 isOperandLiteral (operand * op)
887 opetype = getSpec (operandType (op));
889 if (IS_LITERAL (opetype))
895 /*-----------------------------------------------------------------*/
896 /* isOperandInFarSpace - will return true if operand is in farSpace */
897 /*-----------------------------------------------------------------*/
899 isOperandInFarSpace (operand * op)
909 if (!IS_TRUE_SYMOP (op))
912 etype = SPIL_LOC (op)->etype;
918 etype = getSpec (operandType (op));
920 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
923 /*------------------------------------------------------------------*/
924 /* isOperandInDirSpace - will return true if operand is in dirSpace */
925 /*------------------------------------------------------------------*/
927 isOperandInDirSpace (operand * op)
937 if (!IS_TRUE_SYMOP (op))
940 etype = SPIL_LOC (op)->etype;
946 etype = getSpec (operandType (op));
948 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
951 /*--------------------------------------------------------------------*/
952 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
953 /*--------------------------------------------------------------------*/
955 isOperandInCodeSpace (operand * op)
965 etype = getSpec (operandType (op));
967 if (!IS_TRUE_SYMOP (op))
970 etype = SPIL_LOC (op)->etype;
976 etype = getSpec (operandType (op));
978 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
981 /*-----------------------------------------------------------------*/
982 /* isOperandOnStack - will return true if operand is on stack */
983 /*-----------------------------------------------------------------*/
985 isOperandOnStack (operand * op)
995 etype = getSpec (operandType (op));
996 if (IN_STACK (etype) ||
997 OP_SYMBOL(op)->onStack ||
998 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1004 /*-----------------------------------------------------------------*/
1005 /* operandLitValue - literal value of an operand */
1006 /*-----------------------------------------------------------------*/
1008 operandLitValue (operand * op)
1010 assert (isOperandLiteral (op));
1012 return floatFromVal (op->operand.valOperand);
1015 /*-----------------------------------------------------------------*/
1016 /* getBuiltInParms - returns parameters to a builtin functions */
1017 /*-----------------------------------------------------------------*/
1018 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1023 /* builtin functions uses only SEND for parameters */
1024 while (ic->op != CALL) {
1025 assert(ic->op == SEND && ic->builtinSEND);
1026 ic->generated = 1; /* mark the icode as generated */
1027 parms[*pcount] = IC_LEFT(ic);
1033 /* make sure this is a builtin function call */
1034 assert(IS_SYMOP(IC_LEFT(ic)));
1035 ftype = operandType(IC_LEFT(ic));
1036 assert(IFFUNC_ISBUILTIN(ftype));
1040 /*-----------------------------------------------------------------*/
1041 /* operandOperation - perforoms operations on operands */
1042 /*-----------------------------------------------------------------*/
1044 operandOperation (operand * left, operand * right,
1045 int op, sym_link * type)
1047 sym_link *let , *ret=NULL;
1048 operand *retval = (operand *) 0;
1050 assert (isOperandLiteral (left));
1051 let = getSpec(operandType(left));
1053 assert (isOperandLiteral (right));
1054 ret = getSpec(operandType(left));
1060 retval = operandFromValue (valCastLiteral (type,
1061 operandLitValue (left) +
1062 operandLitValue (right)));
1065 retval = operandFromValue (valCastLiteral (type,
1066 operandLitValue (left) -
1067 operandLitValue (right)));
1070 retval = operandFromValue (valCastLiteral (type,
1071 operandLitValue (left) *
1072 operandLitValue (right)));
1075 if ((unsigned long) operandLitValue (right) == 0)
1077 werror (E_DIVIDE_BY_ZERO);
1082 retval = operandFromValue (valCastLiteral (type,
1083 operandLitValue (left) /
1084 operandLitValue (right)));
1087 if ((unsigned long) operandLitValue (right) == 0) {
1088 werror (E_DIVIDE_BY_ZERO);
1092 retval = operandFromLit ((SPEC_USIGN(let) ?
1093 (unsigned long) operandLitValue (left) :
1094 (long) operandLitValue (left)) %
1096 (unsigned long) operandLitValue (right) :
1097 (long) operandLitValue (right)));
1101 retval = operandFromLit ((SPEC_USIGN(let) ?
1102 (unsigned long) operandLitValue (left) :
1103 (long) operandLitValue (left)) <<
1105 (unsigned long) operandLitValue (right) :
1106 (long) operandLitValue (right)));
1109 double lval = operandLitValue(left), rval = operandLitValue(right);
1111 switch ((SPEC_USIGN(let) ? 2 : 0) + (SPEC_USIGN(ret) ? 1 : 0))
1113 case 0: // left=unsigned right=unsigned
1114 res=(unsigned long)lval >> (unsigned long)rval;
1116 case 1: // left=unsigned right=signed
1117 res=(unsigned long)lval >> (signed long)rval;
1119 case 2: // left=signed right=unsigned
1120 res=(signed long)lval >> (unsigned long)rval;
1122 case 3: // left=signed right=signed
1123 res=(signed long)lval >> (signed long)rval;
1126 retval = operandFromLit (res);
1130 retval = operandFromLit (operandLitValue (left) ==
1131 operandLitValue (right));
1134 retval = operandFromLit (operandLitValue (left) <
1135 operandLitValue (right));
1138 retval = operandFromLit (operandLitValue (left) <=
1139 operandLitValue (right));
1142 retval = operandFromLit (operandLitValue (left) !=
1143 operandLitValue (right));
1146 retval = operandFromLit (operandLitValue (left) >
1147 operandLitValue (right));
1150 retval = operandFromLit (operandLitValue (left) >=
1151 operandLitValue (right));
1154 retval = operandFromLit ((long)operandLitValue(left) &
1155 (long)operandLitValue(right));
1158 retval = operandFromLit ((long)operandLitValue (left) |
1159 (long)operandLitValue (right));
1162 retval = operandFromLit ((long)operandLitValue (left) ^
1163 (long)operandLitValue (right));
1166 retval = operandFromLit (operandLitValue (left) &&
1167 operandLitValue (right));
1170 retval = operandFromLit (operandLitValue (left) ||
1171 operandLitValue (right));
1175 long i = (long) operandLitValue (left);
1177 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1183 long i = (long) operandLitValue (left);
1185 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1191 retval = operandFromLit (-1 * operandLitValue (left));
1195 retval = operandFromLit (~((long) operandLitValue (left)));
1199 retval = operandFromLit (!operandLitValue (left));
1203 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1204 " operandOperation invalid operator ");
1212 /*-----------------------------------------------------------------*/
1213 /* isOperandEqual - compares two operand & return 1 if they r = */
1214 /*-----------------------------------------------------------------*/
1216 isOperandEqual (operand * left, operand * right)
1218 /* if the pointers are equal then they are equal */
1222 /* if either of them null then false */
1223 if (!left || !right)
1226 if (left->type != right->type)
1229 if (IS_SYMOP (left) && IS_SYMOP (right))
1230 return left->key == right->key;
1232 /* if types are the same */
1236 return isSymbolEqual (left->operand.symOperand,
1237 right->operand.symOperand);
1239 return (floatFromVal (left->operand.valOperand) ==
1240 floatFromVal (right->operand.valOperand));
1242 if (compareType (left->operand.typeOperand,
1243 right->operand.typeOperand) == 1)
1250 /*-------------------------------------------------------------------*/
1251 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1252 /*-------------------------------------------------------------------*/
1254 isiCodeEqual (iCode * left, iCode * right)
1256 /* if the same pointer */
1260 /* if either of them null */
1261 if (!left || !right)
1264 /* if operand are the same */
1265 if (left->op == right->op)
1268 /* compare all the elements depending on type */
1269 if (left->op != IFX)
1271 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1273 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1279 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1281 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1283 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1292 /*-----------------------------------------------------------------*/
1293 /* newiTempFromOp - create a temp Operand with same attributes */
1294 /*-----------------------------------------------------------------*/
1296 newiTempFromOp (operand * op)
1306 nop = newiTempOperand (operandType (op), TRUE);
1307 nop->isaddr = op->isaddr;
1308 nop->isvolatile = op->isvolatile;
1309 nop->isGlobal = op->isGlobal;
1310 nop->isLiteral = op->isLiteral;
1311 nop->usesDefs = op->usesDefs;
1312 nop->isParm = op->isParm;
1316 /*-----------------------------------------------------------------*/
1317 /* operand from operand - creates an operand holder for the type */
1318 /*-----------------------------------------------------------------*/
1320 operandFromOperand (operand * op)
1326 nop = newOperand ();
1327 nop->type = op->type;
1328 nop->isaddr = op->isaddr;
1330 nop->isvolatile = op->isvolatile;
1331 nop->isGlobal = op->isGlobal;
1332 nop->isLiteral = op->isLiteral;
1333 nop->usesDefs = op->usesDefs;
1334 nop->isParm = op->isParm;
1339 nop->operand.symOperand = op->operand.symOperand;
1342 nop->operand.valOperand = op->operand.valOperand;
1345 nop->operand.typeOperand = op->operand.typeOperand;
1352 /*-----------------------------------------------------------------*/
1353 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1354 /*-----------------------------------------------------------------*/
1356 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1358 operand *nop = operandFromOperand (op);
1360 if (nop->type == SYMBOL)
1362 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1363 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1369 /*-----------------------------------------------------------------*/
1370 /* operandFromSymbol - creates an operand from a symbol */
1371 /*-----------------------------------------------------------------*/
1373 operandFromSymbol (symbol * sym)
1378 /* if the symbol's type is a literal */
1379 /* then it is an enumerator type */
1380 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1381 return operandFromValue (valFromType (sym->etype));
1384 sym->key = ++operandKey;
1386 /* if this an implicit variable, means struct/union */
1387 /* member so just return it */
1388 if (sym->implicit || IS_FUNC (sym->type))
1392 op->operand.symOperand = sym;
1394 op->isvolatile = isOperandVolatile (op, TRUE);
1395 op->isGlobal = isOperandGlobal (op);
1399 /* under the following conditions create a
1400 register equivalent for a local symbol */
1401 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1402 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1403 (!(options.model == MODEL_FLAT24)) ) &&
1404 options.stackAuto == 0)
1407 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1408 !IS_FUNC (sym->type) && /* not a function */
1409 !sym->_isparm && /* not a parameter */
1410 sym->level && /* is a local variable */
1411 !sym->addrtaken && /* whose address has not been taken */
1412 !sym->reqv && /* does not already have a reg equivalence */
1413 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1414 !IS_STATIC (sym->etype) && /* and not declared static */
1415 !sym->islbl && /* not a label */
1416 ok && /* farspace check */
1417 !IS_BITVAR (sym->etype) /* not a bit variable */
1421 /* we will use it after all optimizations
1422 and before liveRange calculation */
1423 sym->reqv = newiTempOperand (sym->type, 0);
1424 sym->reqv->key = sym->key;
1425 OP_SYMBOL (sym->reqv)->key = sym->key;
1426 OP_SYMBOL (sym->reqv)->isreqv = 1;
1427 OP_SYMBOL (sym->reqv)->islocal = 1;
1428 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1429 SPIL_LOC (sym->reqv) = sym;
1432 if (!IS_AGGREGATE (sym->type))
1436 op->operand.symOperand = sym;
1439 op->isvolatile = isOperandVolatile (op, TRUE);
1440 op->isGlobal = isOperandGlobal (op);
1441 op->isPtr = IS_PTR (operandType (op));
1442 op->isParm = sym->_isparm;
1447 /* itemp = &[_symbol] */
1449 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1450 IC_LEFT (ic)->type = SYMBOL;
1451 IC_LEFT (ic)->operand.symOperand = sym;
1452 IC_LEFT (ic)->key = sym->key;
1453 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1454 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1455 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1458 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1459 if (IS_ARRAY (sym->type))
1461 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1462 IC_RESULT (ic)->isaddr = 0;
1465 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1469 return IC_RESULT (ic);
1472 /*-----------------------------------------------------------------*/
1473 /* operandFromValue - creates an operand from value */
1474 /*-----------------------------------------------------------------*/
1476 operandFromValue (value * val)
1480 /* if this is a symbol then do the symbol thing */
1482 return operandFromSymbol (val->sym);
1484 /* this is not a symbol */
1487 op->operand.valOperand = val;
1488 op->isLiteral = isOperandLiteral (op);
1492 /*-----------------------------------------------------------------*/
1493 /* operandFromLink - operand from typeChain */
1494 /*-----------------------------------------------------------------*/
1496 operandFromLink (sym_link * type)
1500 /* operand from sym_link */
1506 op->operand.typeOperand = copyLinkChain (type);
1510 /*-----------------------------------------------------------------*/
1511 /* operandFromLit - makes an operand from a literal value */
1512 /*-----------------------------------------------------------------*/
1514 operandFromLit (double i)
1516 return operandFromValue (valueFromLit (i));
1519 /*-----------------------------------------------------------------*/
1520 /* operandFromAst - creates an operand from an ast */
1521 /*-----------------------------------------------------------------*/
1523 operandFromAst (ast * tree,int lvl)
1529 /* depending on type do */
1533 return ast2iCode (tree,lvl+1);
1537 return operandFromValue (tree->opval.val);
1541 return operandFromLink (tree->opval.lnk);
1545 /* Just to keep the comiler happy */
1546 return (operand *) 0;
1549 /*-----------------------------------------------------------------*/
1550 /* setOperandType - sets the operand's type to the given type */
1551 /*-----------------------------------------------------------------*/
1553 setOperandType (operand * op, sym_link * type)
1555 /* depending on the type of operand */
1560 op->operand.valOperand->etype =
1561 getSpec (op->operand.valOperand->type =
1562 copyLinkChain (type));
1566 if (op->operand.symOperand->isitmp)
1567 op->operand.symOperand->etype =
1568 getSpec (op->operand.symOperand->type =
1569 copyLinkChain (type));
1571 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1572 "attempt to modify type of source");
1576 op->operand.typeOperand = copyLinkChain (type);
1581 /*-----------------------------------------------------------------*/
1582 /* Get size in byte of ptr need to access an array */
1583 /*-----------------------------------------------------------------*/
1585 getArraySizePtr (operand * op)
1587 sym_link *ltype = operandType(op);
1591 int size = getSize(ltype);
1592 return(IS_GENPTR(ltype)?(size-1):size);
1597 sym_link *letype = getSpec(ltype);
1598 switch (PTR_TYPE (SPEC_OCLS (letype)))
1610 return (GPTRSIZE-1);
1619 /*-----------------------------------------------------------------*/
1620 /* perform "usual unary conversions" */
1621 /*-----------------------------------------------------------------*/
1623 usualUnaryConversions (operand * op)
1625 if (IS_INTEGRAL (operandType (op)))
1627 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1630 return geniCodeCast (INTTYPE, op, TRUE);
1636 /*-----------------------------------------------------------------*/
1637 /* perform "usual binary conversions" */
1638 /*-----------------------------------------------------------------*/
1640 usualBinaryConversions (operand ** op1, operand ** op2)
1643 sym_link *rtype = operandType (*op2);
1644 sym_link *ltype = operandType (*op1);
1646 ctype = computeType (ltype, rtype);
1648 *op1 = geniCodeCast (ctype, *op1, TRUE);
1649 *op2 = geniCodeCast (ctype, *op2, TRUE);
1654 /*-----------------------------------------------------------------*/
1655 /* geniCodeValueAtAddress - generate intermeditate code for value */
1657 /*-----------------------------------------------------------------*/
1659 geniCodeRValue (operand * op, bool force)
1662 sym_link *type = operandType (op);
1663 sym_link *etype = getSpec (type);
1665 /* if this is an array & already */
1666 /* an address then return this */
1667 if (IS_AGGREGATE (type) ||
1668 (IS_PTR (type) && !force && !op->isaddr))
1669 return operandFromOperand (op);
1671 /* if this is not an address then must be */
1672 /* rvalue already so return this one */
1676 /* if this is not a temp symbol then */
1677 if (!IS_ITEMP (op) &&
1679 !IN_FARSPACE (SPEC_OCLS (etype)))
1681 op = operandFromOperand (op);
1686 if (IS_SPEC (type) &&
1687 IS_TRUE_SYMOP (op) &&
1688 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1689 (options.model == MODEL_FLAT24) ))
1691 op = operandFromOperand (op);
1696 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1697 if (IS_PTR (type) && op->isaddr && force)
1700 type = copyLinkChain (type);
1702 IC_RESULT (ic) = newiTempOperand (type, 1);
1703 IC_RESULT (ic)->isaddr = 0;
1705 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1709 return IC_RESULT (ic);
1712 /*-----------------------------------------------------------------*/
1713 /* geniCodeCast - changes the value from one type to another */
1714 /*-----------------------------------------------------------------*/
1716 geniCodeCast (sym_link * type, operand * op, bool implicit)
1720 sym_link *opetype = getSpec (optype = operandType (op));
1724 /* one of them has size zero then error */
1725 if (IS_VOID (optype))
1727 werror (E_CAST_ZERO);
1731 /* if the operand is already the desired type then do nothing */
1732 if (compareType (type, optype) == 1)
1735 /* if this is a literal then just change the type & return */
1736 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1737 return operandFromValue (valCastLiteral (type,
1738 operandLitValue (op)));
1740 /* if casting to/from pointers, do some checking */
1741 if (IS_PTR(type)) { // to a pointer
1742 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1743 if (IS_INTEGRAL(optype)) {
1744 // maybe this is NULL, than it's ok.
1745 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1746 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1747 // no way to set the storage
1748 if (IS_LITERAL(optype)) {
1749 werror(E_LITERAL_GENERIC);
1752 werror(E_NONPTR2_GENPTR);
1755 } else if (implicit) {
1756 werror(W_INTEGRAL2PTR_NOCAST);
1761 // shouldn't do that with float, array or structure unless to void
1762 if (!IS_VOID(getSpec(type)) &&
1763 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1764 werror(E_INCOMPAT_TYPES);
1768 } else { // from a pointer to a pointer
1769 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1770 // if not a pointer to a function
1771 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1772 if (implicit) { // if not to generic, they have to match
1773 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1774 werror(E_INCOMPAT_PTYPES);
1781 } else { // to a non pointer
1782 if (IS_PTR(optype)) { // from a pointer
1783 if (implicit) { // sneaky
1784 if (IS_INTEGRAL(type)) {
1785 werror(W_PTR2INTEGRAL_NOCAST);
1787 } else { // shouldn't do that with float, array or structure
1788 werror(E_INCOMPAT_TYPES);
1795 printFromToType (optype, type);
1798 /* if they are the same size create an assignment */
1799 if (getSize (type) == getSize (optype) &&
1800 !IS_BITFIELD (type) &&
1802 !IS_FLOAT (optype) &&
1803 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1804 (!IS_SPEC (type) && !IS_SPEC (optype))))
1807 ic = newiCode ('=', NULL, op);
1808 IC_RESULT (ic) = newiTempOperand (type, 0);
1809 SPIL_LOC (IC_RESULT (ic)) =
1810 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1811 IC_RESULT (ic)->isaddr = 0;
1815 ic = newiCode (CAST, operandFromLink (type),
1816 geniCodeRValue (op, FALSE));
1818 IC_RESULT (ic) = newiTempOperand (type, 0);
1821 /* preserve the storage class & output class */
1822 /* of the original variable */
1823 restype = getSpec (operandType (IC_RESULT (ic)));
1824 if (!IS_LITERAL(opetype))
1825 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1826 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1829 return IC_RESULT (ic);
1832 /*-----------------------------------------------------------------*/
1833 /* geniCodeLabel - will create a Label */
1834 /*-----------------------------------------------------------------*/
1836 geniCodeLabel (symbol * label)
1840 ic = newiCodeLabelGoto (LABEL, label);
1844 /*-----------------------------------------------------------------*/
1845 /* geniCodeGoto - will create a Goto */
1846 /*-----------------------------------------------------------------*/
1848 geniCodeGoto (symbol * label)
1852 ic = newiCodeLabelGoto (GOTO, label);
1856 /*-----------------------------------------------------------------*/
1857 /* geniCodeMultiply - gen intermediate code for multiplication */
1858 /*-----------------------------------------------------------------*/
1860 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1867 /* if they are both literal then we know the result */
1868 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1869 return operandFromValue (valMult (left->operand.valOperand,
1870 right->operand.valOperand));
1872 if (IS_LITERAL(retype)) {
1873 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1876 resType = usualBinaryConversions (&left, &right);
1878 rtype = operandType (right);
1879 retype = getSpec (rtype);
1880 ltype = operandType (left);
1881 letype = getSpec (ltype);
1885 SPEC_NOUN(getSpec(resType))=V_INT;
1888 /* if the right is a literal & power of 2 */
1889 /* then make it a left shift */
1890 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1891 efficient in most cases than 2 bytes result = 2 bytes << literal
1892 if port has 1 byte muldiv */
1893 if (p2 && !IS_FLOAT (letype) &&
1894 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1895 (port->support.muldiv == 1)))
1897 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1899 /* LEFT_OP need same size for left and result, */
1900 left = geniCodeCast (resType, left, TRUE);
1901 ltype = operandType (left);
1903 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1907 ic = newiCode ('*', left, right); /* normal multiplication */
1908 /* if the size left or right > 1 then support routine */
1909 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1913 IC_RESULT (ic) = newiTempOperand (resType, 1);
1916 return IC_RESULT (ic);
1919 /*-----------------------------------------------------------------*/
1920 /* geniCodeDivision - gen intermediate code for division */
1921 /*-----------------------------------------------------------------*/
1923 geniCodeDivision (operand * left, operand * right)
1928 sym_link *rtype = operandType (right);
1929 sym_link *retype = getSpec (rtype);
1930 sym_link *ltype = operandType (left);
1931 sym_link *letype = getSpec (ltype);
1933 resType = usualBinaryConversions (&left, &right);
1935 /* if the right is a literal & power of 2
1936 and left is unsigned then make it a
1938 if (IS_LITERAL (retype) &&
1939 !IS_FLOAT (letype) &&
1940 SPEC_USIGN(letype) &&
1941 (p2 = powof2 ((unsigned long)
1942 floatFromVal (right->operand.valOperand)))) {
1943 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1947 ic = newiCode ('/', left, right); /* normal division */
1948 /* if the size left or right > 1 then support routine */
1949 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1952 IC_RESULT (ic) = newiTempOperand (resType, 0);
1955 return IC_RESULT (ic);
1957 /*-----------------------------------------------------------------*/
1958 /* geniCodeModulus - gen intermediate code for modulus */
1959 /*-----------------------------------------------------------------*/
1961 geniCodeModulus (operand * left, operand * right)
1967 /* if they are both literal then we know the result */
1968 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1969 return operandFromValue (valMod (left->operand.valOperand,
1970 right->operand.valOperand));
1972 resType = usualBinaryConversions (&left, &right);
1974 /* now they are the same size */
1975 ic = newiCode ('%', left, right);
1977 /* if the size left or right > 1 then support routine */
1978 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1980 IC_RESULT (ic) = newiTempOperand (resType, 0);
1983 return IC_RESULT (ic);
1986 /*-----------------------------------------------------------------*/
1987 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1988 /*-----------------------------------------------------------------*/
1990 geniCodePtrPtrSubtract (operand * left, operand * right)
1996 /* if they are both literals then */
1997 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1999 result = operandFromValue (valMinus (left->operand.valOperand,
2000 right->operand.valOperand));
2004 ic = newiCode ('-', left, right);
2006 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2010 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2014 // should we really do this? is this ANSI?
2015 return geniCodeDivision (result,
2016 operandFromLit (getSize (ltype->next)));
2019 /*-----------------------------------------------------------------*/
2020 /* geniCodeSubtract - generates code for subtraction */
2021 /*-----------------------------------------------------------------*/
2023 geniCodeSubtract (operand * left, operand * right)
2030 /* if they both pointers then */
2031 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2032 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2033 return geniCodePtrPtrSubtract (left, right);
2035 /* if they are both literal then we know the result */
2036 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2037 && left->isLiteral && right->isLiteral)
2038 return operandFromValue (valMinus (left->operand.valOperand,
2039 right->operand.valOperand));
2041 /* if left is an array or pointer */
2042 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2044 isarray = left->isaddr;
2045 right = geniCodeMultiply (right,
2046 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2047 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2050 { /* make them the same size */
2051 resType = usualBinaryConversions (&left, &right);
2054 ic = newiCode ('-', left, right);
2056 IC_RESULT (ic) = newiTempOperand (resType, 1);
2057 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2059 /* if left or right is a float */
2060 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2064 return IC_RESULT (ic);
2067 /*-----------------------------------------------------------------*/
2068 /* geniCodeAdd - generates iCode for addition */
2069 /*-----------------------------------------------------------------*/
2071 geniCodeAdd (operand * left, operand * right, int lvl)
2080 /* if left is an array then array access */
2081 if (IS_ARRAY (ltype))
2082 return geniCodeArray (left, right,lvl);
2085 /* if the right side is LITERAL zero */
2086 /* return the left side */
2087 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2090 /* if left is literal zero return right */
2091 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2094 /* if left is a pointer then size */
2095 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2097 isarray = left->isaddr;
2098 // there is no need to multiply with 1
2099 if (getSize(ltype->next)!=1) {
2100 size = operandFromLit (getSize (ltype->next));
2101 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2103 resType = copyLinkChain (ltype);
2106 { // make them the same size
2107 resType = usualBinaryConversions (&left, &right);
2110 /* if they are both literals then we know */
2111 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2112 && left->isLiteral && right->isLiteral)
2113 return operandFromValue (valPlus (valFromType (letype),
2114 valFromType (retype)));
2116 ic = newiCode ('+', left, right);
2118 IC_RESULT (ic) = newiTempOperand (resType, 1);
2119 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2121 /* if left or right is a float then support
2123 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2128 return IC_RESULT (ic);
2132 /*-----------------------------------------------------------------*/
2133 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2134 /*-----------------------------------------------------------------*/
2136 aggrToPtr (sym_link * type, bool force)
2142 if (IS_PTR (type) && !force)
2145 etype = getSpec (type);
2149 /* if the output class is generic */
2150 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2151 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2153 /* if the variable was declared a constant */
2154 /* then the pointer points to a constant */
2155 if (IS_CONSTANT (etype))
2156 DCL_PTR_CONST (ptype) = 1;
2158 /* the variable was volatile then pointer to volatile */
2159 if (IS_VOLATILE (etype))
2160 DCL_PTR_VOLATILE (ptype) = 1;
2164 /*-----------------------------------------------------------------*/
2165 /* geniCodeArray2Ptr - array to pointer */
2166 /*-----------------------------------------------------------------*/
2168 geniCodeArray2Ptr (operand * op)
2170 sym_link *optype = operandType (op);
2171 sym_link *opetype = getSpec (optype);
2173 /* set the pointer depending on the storage class */
2174 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2175 DCL_PTR_CONST (optype) = port->mem.code_ro;
2178 /* if the variable was declared a constant */
2179 /* then the pointer points to a constant */
2180 if (IS_CONSTANT (opetype))
2181 DCL_PTR_CONST (optype) = 1;
2183 /* the variable was volatile then pointer to volatile */
2184 if (IS_VOLATILE (opetype))
2185 DCL_PTR_VOLATILE (optype) = 1;
2191 /*-----------------------------------------------------------------*/
2192 /* geniCodeArray - array access */
2193 /*-----------------------------------------------------------------*/
2195 geniCodeArray (operand * left, operand * right,int lvl)
2198 sym_link *ltype = operandType (left);
2202 if (IS_PTR (ltype->next) && left->isaddr)
2204 left = geniCodeRValue (left, FALSE);
2206 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2209 right = geniCodeMultiply (right,
2210 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2212 /* we can check for limits here */
2213 if (isOperandLiteral (right) &&
2216 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2218 werror (E_ARRAY_BOUND);
2219 right = operandFromLit (0);
2222 ic = newiCode ('+', left, right);
2224 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2225 !IS_AGGREGATE (ltype->next) &&
2226 !IS_PTR (ltype->next))
2227 ? ltype : ltype->next), 0);
2229 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2231 return IC_RESULT (ic);
2234 /*-----------------------------------------------------------------*/
2235 /* geniCodeStruct - generates intermediate code for structres */
2236 /*-----------------------------------------------------------------*/
2238 geniCodeStruct (operand * left, operand * right, bool islval)
2241 sym_link *type = operandType (left);
2242 sym_link *etype = getSpec (type);
2244 symbol *element = getStructElement (SPEC_STRUCT (etype),
2245 right->operand.symOperand);
2247 /* add the offset */
2248 ic = newiCode ('+', left, operandFromLit (element->offset));
2250 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2252 /* preserve the storage & output class of the struct */
2253 /* as well as the volatile attribute */
2254 retype = getSpec (operandType (IC_RESULT (ic)));
2255 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2256 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2257 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2259 if (IS_PTR (element->type))
2260 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2262 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2266 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2269 /*-----------------------------------------------------------------*/
2270 /* geniCodePostInc - generate int code for Post increment */
2271 /*-----------------------------------------------------------------*/
2273 geniCodePostInc (operand * op)
2277 sym_link *optype = operandType (op);
2279 operand *rv = (IS_ITEMP (op) ?
2280 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2282 sym_link *rvtype = operandType (rv);
2285 /* if this is not an address we have trouble */
2288 werror (E_LVALUE_REQUIRED, "++");
2292 rOp = newiTempOperand (rvtype, 0);
2293 OP_SYMBOL(rOp)->noSpilLoc = 1;
2296 OP_SYMBOL(rv)->noSpilLoc = 1;
2298 geniCodeAssign (rOp, rv, 0);
2300 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2301 if (IS_FLOAT (rvtype))
2302 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2304 ic = newiCode ('+', rv, operandFromLit (size));
2306 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2309 geniCodeAssign (op, result, 0);
2315 /*-----------------------------------------------------------------*/
2316 /* geniCodePreInc - generate code for preIncrement */
2317 /*-----------------------------------------------------------------*/
2319 geniCodePreInc (operand * op)
2322 sym_link *optype = operandType (op);
2323 operand *rop = (IS_ITEMP (op) ?
2324 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2326 sym_link *roptype = operandType (rop);
2332 werror (E_LVALUE_REQUIRED, "++");
2337 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2338 if (IS_FLOAT (roptype))
2339 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2341 ic = newiCode ('+', rop, operandFromLit (size));
2342 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2346 return geniCodeAssign (op, result, 0);
2349 /*-----------------------------------------------------------------*/
2350 /* geniCodePostDec - generates code for Post decrement */
2351 /*-----------------------------------------------------------------*/
2353 geniCodePostDec (operand * op)
2357 sym_link *optype = operandType (op);
2359 operand *rv = (IS_ITEMP (op) ?
2360 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2362 sym_link *rvtype = operandType (rv);
2365 /* if this is not an address we have trouble */
2368 werror (E_LVALUE_REQUIRED, "--");
2372 rOp = newiTempOperand (rvtype, 0);
2373 OP_SYMBOL(rOp)->noSpilLoc = 1;
2376 OP_SYMBOL(rv)->noSpilLoc = 1;
2378 geniCodeAssign (rOp, rv, 0);
2380 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2381 if (IS_FLOAT (rvtype))
2382 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2384 ic = newiCode ('-', rv, operandFromLit (size));
2386 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2389 geniCodeAssign (op, result, 0);
2395 /*-----------------------------------------------------------------*/
2396 /* geniCodePreDec - generate code for pre decrement */
2397 /*-----------------------------------------------------------------*/
2399 geniCodePreDec (operand * op)
2402 sym_link *optype = operandType (op);
2403 operand *rop = (IS_ITEMP (op) ?
2404 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2406 sym_link *roptype = operandType (rop);
2412 werror (E_LVALUE_REQUIRED, "--");
2417 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2418 if (IS_FLOAT (roptype))
2419 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2421 ic = newiCode ('-', rop, operandFromLit (size));
2422 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2426 return geniCodeAssign (op, result, 0);
2430 /*-----------------------------------------------------------------*/
2431 /* geniCodeBitwise - gen int code for bitWise operators */
2432 /*-----------------------------------------------------------------*/
2434 geniCodeBitwise (operand * left, operand * right,
2435 int oper, sym_link * resType)
2439 left = geniCodeCast (resType, left, TRUE);
2440 right = geniCodeCast (resType, right, TRUE);
2442 ic = newiCode (oper, left, right);
2443 IC_RESULT (ic) = newiTempOperand (resType, 0);
2446 return IC_RESULT (ic);
2449 /*-----------------------------------------------------------------*/
2450 /* geniCodeAddressOf - gens icode for '&' address of operator */
2451 /*-----------------------------------------------------------------*/
2453 geniCodeAddressOf (operand * op)
2457 sym_link *optype = operandType (op);
2458 sym_link *opetype = getSpec (optype);
2460 /* lvalue check already done in decorateType */
2461 /* this must be a lvalue */
2462 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2463 /* werror (E_LVALUE_REQUIRED,"&"); */
2468 p->class = DECLARATOR;
2470 /* set the pointer depending on the storage class */
2471 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2472 DCL_PTR_CONST (p) = port->mem.code_ro;
2474 /* make sure we preserve the const & volatile */
2475 if (IS_CONSTANT (opetype))
2476 DCL_PTR_CONST (p) = 1;
2478 if (IS_VOLATILE (opetype))
2479 DCL_PTR_VOLATILE (p) = 1;
2481 p->next = copyLinkChain (optype);
2483 /* if already a temp */
2486 setOperandType (op, p);
2491 /* other wise make this of the type coming in */
2492 ic = newiCode (ADDRESS_OF, op, NULL);
2493 IC_RESULT (ic) = newiTempOperand (p, 1);
2494 IC_RESULT (ic)->isaddr = 0;
2496 return IC_RESULT (ic);
2498 /*-----------------------------------------------------------------*/
2499 /* setOClass - sets the output class depending on the pointer type */
2500 /*-----------------------------------------------------------------*/
2502 setOClass (sym_link * ptr, sym_link * spec)
2504 switch (DCL_TYPE (ptr))
2507 SPEC_OCLS (spec) = data;
2511 SPEC_OCLS (spec) = generic;
2515 SPEC_OCLS (spec) = xdata;
2519 SPEC_OCLS (spec) = code;
2523 SPEC_OCLS (spec) = idata;
2527 SPEC_OCLS (spec) = xstack;
2531 SPEC_OCLS (spec) = eeprom;
2540 /*-----------------------------------------------------------------*/
2541 /* geniCodeDerefPtr - dereference pointer with '*' */
2542 /*-----------------------------------------------------------------*/
2544 geniCodeDerefPtr (operand * op,int lvl)
2546 sym_link *rtype, *retype;
2547 sym_link *optype = operandType (op);
2549 /* if this is a pointer then generate the rvalue */
2550 if (IS_PTR (optype))
2552 if (IS_TRUE_SYMOP (op))
2555 op = geniCodeRValue (op, TRUE);
2558 op = geniCodeRValue (op, TRUE);
2561 /* now get rid of the pointer part */
2562 if (isLvaluereq(lvl) && IS_ITEMP (op))
2564 retype = getSpec (rtype = copyLinkChain (optype));
2568 retype = getSpec (rtype = copyLinkChain (optype->next));
2571 /* if this is a pointer then outputclass needs 2b updated */
2572 if (IS_PTR (optype))
2573 setOClass (optype, retype);
2575 op->isGptr = IS_GENPTR (optype);
2577 /* if the pointer was declared as a constant */
2578 /* then we cannot allow assignment to the derefed */
2579 if (IS_PTR_CONST (optype))
2580 SPEC_CONST (retype) = 1;
2582 op->isaddr = (IS_PTR (rtype) ||
2583 IS_STRUCT (rtype) ||
2588 if (!isLvaluereq(lvl))
2589 op = geniCodeRValue (op, TRUE);
2591 setOperandType (op, rtype);
2596 /*-----------------------------------------------------------------*/
2597 /* geniCodeUnaryMinus - does a unary minus of the operand */
2598 /*-----------------------------------------------------------------*/
2600 geniCodeUnaryMinus (operand * op)
2603 sym_link *optype = operandType (op);
2605 if (IS_LITERAL (optype))
2606 return operandFromLit (-floatFromVal (op->operand.valOperand));
2608 ic = newiCode (UNARYMINUS, op, NULL);
2609 IC_RESULT (ic) = newiTempOperand (optype, 0);
2611 return IC_RESULT (ic);
2614 /*-----------------------------------------------------------------*/
2615 /* geniCodeLeftShift - gen i code for left shift */
2616 /*-----------------------------------------------------------------*/
2618 geniCodeLeftShift (operand * left, operand * right)
2622 ic = newiCode (LEFT_OP, left, right);
2623 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2625 return IC_RESULT (ic);
2628 /*-----------------------------------------------------------------*/
2629 /* geniCodeRightShift - gen i code for right shift */
2630 /*-----------------------------------------------------------------*/
2632 geniCodeRightShift (operand * left, operand * right)
2636 ic = newiCode (RIGHT_OP, left, right);
2637 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2639 return IC_RESULT (ic);
2642 /*-----------------------------------------------------------------*/
2643 /* geniCodeLogic- logic code */
2644 /*-----------------------------------------------------------------*/
2646 geniCodeLogic (operand * left, operand * right, int op)
2650 sym_link *rtype = operandType (right);
2651 sym_link *ltype = operandType (left);
2653 /* left is integral type and right is literal then
2654 check if the literal value is within bounds */
2655 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2657 checkConstantRange(ltype,
2658 OP_VALUE(right), "compare operation", 1);
2661 ctype = usualBinaryConversions (&left, &right);
2663 ic = newiCode (op, left, right);
2664 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2666 /* if comparing float
2667 and not a '==' || '!=' || '&&' || '||' (these
2669 if (IS_FLOAT(ctype) &&
2677 return IC_RESULT (ic);
2680 /*-----------------------------------------------------------------*/
2681 /* geniCodeUnary - for a a generic unary operation */
2682 /*-----------------------------------------------------------------*/
2684 geniCodeUnary (operand * op, int oper)
2686 iCode *ic = newiCode (oper, op, NULL);
2688 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2690 return IC_RESULT (ic);
2693 /*-----------------------------------------------------------------*/
2694 /* geniCodeConditional - geniCode for '?' ':' operation */
2695 /*-----------------------------------------------------------------*/
2697 geniCodeConditional (ast * tree,int lvl)
2700 symbol *falseLabel = newiTempLabel (NULL);
2701 symbol *exitLabel = newiTempLabel (NULL);
2702 operand *cond = ast2iCode (tree->left,lvl+1);
2703 operand *true, *false, *result;
2705 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2709 true = ast2iCode (tree->right->left,lvl+1);
2711 /* move the value to a new Operand */
2712 result = newiTempOperand (tree->right->ftype, 0);
2713 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2715 /* generate an unconditional goto */
2716 geniCodeGoto (exitLabel);
2718 /* now for the right side */
2719 geniCodeLabel (falseLabel);
2721 false = ast2iCode (tree->right->right,lvl+1);
2722 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2724 /* create the exit label */
2725 geniCodeLabel (exitLabel);
2730 /*-----------------------------------------------------------------*/
2731 /* geniCodeAssign - generate code for assignment */
2732 /*-----------------------------------------------------------------*/
2734 geniCodeAssign (operand * left, operand * right, int nosupdate)
2737 sym_link *ltype = operandType (left);
2738 sym_link *rtype = operandType (right);
2740 if (!left->isaddr && !IS_ITEMP (left))
2742 werror (E_LVALUE_REQUIRED, "assignment");
2746 /* left is integral type and right is literal then
2747 check if the literal value is within bounds */
2748 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2750 checkConstantRange(ltype,
2751 OP_VALUE(right), "= operation", 0);
2754 /* if the left & right type don't exactly match */
2755 /* if pointer set then make sure the check is
2756 done with the type & not the pointer */
2757 /* then cast rights type to left */
2759 /* first check the type for pointer assignement */
2760 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2761 compareType (ltype, rtype) <= 0)
2763 if (compareType (ltype->next, rtype) < 0)
2764 right = geniCodeCast (ltype->next, right, TRUE);
2766 else if (compareType (ltype, rtype) < 0)
2767 right = geniCodeCast (ltype, right, TRUE);
2769 /* if left is a true symbol & ! volatile
2770 create an assignment to temporary for
2771 the right & then assign this temporary
2772 to the symbol this is SSA . isn't it simple
2773 and folks have published mountains of paper on it */
2774 if (IS_TRUE_SYMOP (left) &&
2775 !isOperandVolatile (left, FALSE) &&
2776 isOperandGlobal (left))
2780 if (IS_TRUE_SYMOP (right))
2781 sym = OP_SYMBOL (right);
2782 ic = newiCode ('=', NULL, right);
2783 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2784 SPIL_LOC (right) = sym;
2788 ic = newiCode ('=', NULL, right);
2789 IC_RESULT (ic) = left;
2792 /* if left isgptr flag is set then support
2793 routine will be required */
2797 ic->nosupdate = nosupdate;
2801 /*-----------------------------------------------------------------*/
2802 /* geniCodeSEParms - generate code for side effecting fcalls */
2803 /*-----------------------------------------------------------------*/
2805 geniCodeSEParms (ast * parms,int lvl)
2810 if (parms->type == EX_OP && parms->opval.op == PARAM)
2812 geniCodeSEParms (parms->left,lvl);
2813 geniCodeSEParms (parms->right,lvl);
2817 /* hack don't like this but too lazy to think of
2819 if (IS_ADDRESS_OF_OP (parms))
2820 parms->left->lvalue = 1;
2822 if (IS_CAST_OP (parms) &&
2823 IS_PTR (parms->ftype) &&
2824 IS_ADDRESS_OF_OP (parms->right))
2825 parms->right->left->lvalue = 1;
2827 parms->opval.oprnd =
2828 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2830 parms->type = EX_OPERAND;
2831 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2832 SPEC_ARGREG(parms->ftype);
2835 /*-----------------------------------------------------------------*/
2836 /* geniCodeParms - generates parameters */
2837 /*-----------------------------------------------------------------*/
2839 geniCodeParms (ast * parms, value *argVals, int *stack,
2840 sym_link * fetype, symbol * func,int lvl)
2848 if (argVals==NULL) {
2850 argVals=FUNC_ARGS(func->type);
2853 /* if this is a param node then do the left & right */
2854 if (parms->type == EX_OP && parms->opval.op == PARAM)
2856 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2857 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2861 /* get the parameter value */
2862 if (parms->type == EX_OPERAND)
2863 pval = parms->opval.oprnd;
2866 /* maybe this else should go away ?? */
2867 /* hack don't like this but too lazy to think of
2869 if (IS_ADDRESS_OF_OP (parms))
2870 parms->left->lvalue = 1;
2872 if (IS_CAST_OP (parms) &&
2873 IS_PTR (parms->ftype) &&
2874 IS_ADDRESS_OF_OP (parms->right))
2875 parms->right->left->lvalue = 1;
2877 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2880 /* if register parm then make it a send */
2881 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2882 IFFUNC_ISBUILTIN(func->type))
2884 ic = newiCode (SEND, pval, NULL);
2885 ic->argreg = SPEC_ARGREG(parms->etype);
2886 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2891 /* now decide whether to push or assign */
2892 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2896 operand *top = operandFromSymbol (argVals->sym);
2897 /* clear useDef and other bitVectors */
2898 OP_USES_SET ((top), OP_DEFS_SET ((top), OP_SYMBOL(top)->clashes = NULL));
2899 geniCodeAssign (top, pval, 1);
2903 sym_link *p = operandType (pval);
2905 ic = newiCode (IPUSH, pval, NULL);
2907 /* update the stack adjustment */
2908 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2913 argVals=argVals->next;
2917 /*-----------------------------------------------------------------*/
2918 /* geniCodeCall - generates temp code for calling */
2919 /*-----------------------------------------------------------------*/
2921 geniCodeCall (operand * left, ast * parms,int lvl)
2925 sym_link *type, *etype;
2928 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2929 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2930 werror (E_FUNCTION_EXPECTED);
2934 /* take care of parameters with side-effecting
2935 function calls in them, this is required to take care
2936 of overlaying function parameters */
2937 geniCodeSEParms (parms,lvl);
2939 /* first the parameters */
2940 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2942 /* now call : if symbol then pcall */
2943 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
2944 ic = newiCode (PCALL, left, NULL);
2946 ic = newiCode (CALL, left, NULL);
2949 type = copyLinkChain (operandType (left)->next);
2950 etype = getSpec (type);
2951 SPEC_EXTR (etype) = 0;
2952 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2956 /* stack adjustment after call */
2957 ic->parmBytes = stack;
2962 /*-----------------------------------------------------------------*/
2963 /* geniCodeReceive - generate intermediate code for "receive" */
2964 /*-----------------------------------------------------------------*/
2966 geniCodeReceive (value * args)
2968 /* for all arguments that are passed in registers */
2972 if (IS_REGPARM (args->etype))
2974 operand *opr = operandFromValue (args);
2976 symbol *sym = OP_SYMBOL (opr);
2979 /* we will use it after all optimizations
2980 and before liveRange calculation */
2981 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2984 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2985 options.stackAuto == 0 &&
2986 (!(options.model == MODEL_FLAT24)) )
2991 opl = newiTempOperand (args->type, 0);
2993 sym->reqv->key = sym->key;
2994 OP_SYMBOL (sym->reqv)->key = sym->key;
2995 OP_SYMBOL (sym->reqv)->isreqv = 1;
2996 OP_SYMBOL (sym->reqv)->islocal = 0;
2997 SPIL_LOC (sym->reqv) = sym;
3001 ic = newiCode (RECEIVE, NULL, NULL);
3002 ic->argreg = SPEC_ARGREG(args->etype);
3004 currFunc->recvSize = getSize (sym->type);
3007 IC_RESULT (ic) = opr;
3015 /*-----------------------------------------------------------------*/
3016 /* geniCodeFunctionBody - create the function body */
3017 /*-----------------------------------------------------------------*/
3019 geniCodeFunctionBody (ast * tree,int lvl)
3026 /* reset the auto generation */
3032 func = ast2iCode (tree->left,lvl+1);
3033 fetype = getSpec (operandType (func));
3035 savelineno = lineno;
3036 lineno = OP_SYMBOL (func)->lineDef;
3037 /* create an entry label */
3038 geniCodeLabel (entryLabel);
3039 lineno = savelineno;
3041 /* create a proc icode */
3042 ic = newiCode (FUNCTION, func, NULL);
3043 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3047 /* for all parameters that are passed
3048 on registers add a "receive" */
3049 geniCodeReceive (tree->values.args);
3051 /* generate code for the body */
3052 ast2iCode (tree->right,lvl+1);
3054 /* create a label for return */
3055 geniCodeLabel (returnLabel);
3057 /* now generate the end proc */
3058 ic = newiCode (ENDFUNCTION, func, NULL);
3063 /*-----------------------------------------------------------------*/
3064 /* geniCodeReturn - gen icode for 'return' statement */
3065 /*-----------------------------------------------------------------*/
3067 geniCodeReturn (operand * op)
3071 /* if the operand is present force an rvalue */
3073 op = geniCodeRValue (op, FALSE);
3075 ic = newiCode (RETURN, op, NULL);
3079 /*-----------------------------------------------------------------*/
3080 /* geniCodeIfx - generates code for extended if statement */
3081 /*-----------------------------------------------------------------*/
3083 geniCodeIfx (ast * tree,int lvl)
3086 operand *condition = ast2iCode (tree->left,lvl+1);
3089 /* if condition is null then exit */
3093 condition = geniCodeRValue (condition, FALSE);
3095 cetype = getSpec (operandType (condition));
3096 /* if the condition is a literal */
3097 if (IS_LITERAL (cetype))
3099 if (floatFromVal (condition->operand.valOperand))
3101 if (tree->trueLabel)
3102 geniCodeGoto (tree->trueLabel);
3108 if (tree->falseLabel)
3109 geniCodeGoto (tree->falseLabel);
3116 if (tree->trueLabel)
3118 ic = newiCodeCondition (condition,
3123 if (tree->falseLabel)
3124 geniCodeGoto (tree->falseLabel);
3128 ic = newiCodeCondition (condition,
3135 ast2iCode (tree->right,lvl+1);
3138 /*-----------------------------------------------------------------*/
3139 /* geniCodeJumpTable - tries to create a jump table for switch */
3140 /*-----------------------------------------------------------------*/
3142 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3144 int min = 0, max = 0, t, cnt = 0;
3151 if (!tree || !caseVals)
3154 /* the criteria for creating a jump table is */
3155 /* all integer numbers between the maximum & minimum must */
3156 /* be present , the maximum value should not exceed 255 */
3157 min = max = (int) floatFromVal (vch = caseVals);
3158 SNPRINTF (buffer, sizeof(buffer),
3160 tree->values.switchVals.swNum,
3162 addSet (&labels, newiTempLabel (buffer));
3164 /* if there is only one case value then no need */
3165 if (!(vch = vch->next))
3170 if (((t = (int) floatFromVal (vch)) - max) != 1)
3172 SNPRINTF (buffer, sizeof(buffer),
3174 tree->values.switchVals.swNum,
3176 addSet (&labels, newiTempLabel (buffer));
3182 /* if the number of case statements <= 2 then */
3183 /* it is not economical to create the jump table */
3184 /* since two compares are needed for boundary conditions */
3185 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3188 if (tree->values.switchVals.swDefault)
3190 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3194 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3198 falseLabel = newiTempLabel (buffer);
3200 /* so we can create a jumptable */
3201 /* first we rule out the boundary conditions */
3202 /* if only optimization says so */
3203 if (!optimize.noJTabBoundary)
3205 sym_link *cetype = getSpec (operandType (cond));
3206 /* no need to check the lower bound if
3207 the condition is unsigned & minimum value is zero */
3208 if (!(min == 0 && SPEC_USIGN (cetype)))
3210 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3211 ic = newiCodeCondition (boundary, falseLabel, NULL);
3215 /* now for upper bounds */
3216 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3217 ic = newiCodeCondition (boundary, falseLabel, NULL);
3221 /* if the min is not zero then we no make it zero */
3224 cond = geniCodeSubtract (cond, operandFromLit (min));
3225 setOperandType (cond, UCHARTYPE);
3228 /* now create the jumptable */
3229 ic = newiCode (JUMPTABLE, NULL, NULL);
3230 IC_JTCOND (ic) = cond;
3231 IC_JTLABELS (ic) = labels;
3236 /*-----------------------------------------------------------------*/
3237 /* geniCodeSwitch - changes a switch to a if statement */
3238 /*-----------------------------------------------------------------*/
3240 geniCodeSwitch (ast * tree,int lvl)
3243 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3244 value *caseVals = tree->values.switchVals.swVals;
3245 symbol *trueLabel, *falseLabel;
3247 /* if we can make this a jump table */
3248 if (geniCodeJumpTable (cond, caseVals, tree))
3249 goto jumpTable; /* no need for the comparison */
3251 /* for the cases defined do */
3255 operand *compare = geniCodeLogic (cond,
3256 operandFromValue (caseVals),
3259 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3260 tree->values.switchVals.swNum,
3261 (int) floatFromVal (caseVals));
3262 trueLabel = newiTempLabel (buffer);
3264 ic = newiCodeCondition (compare, trueLabel, NULL);
3266 caseVals = caseVals->next;
3271 /* if default is present then goto break else break */
3272 if (tree->values.switchVals.swDefault)
3274 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3278 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3281 falseLabel = newiTempLabel (buffer);
3282 geniCodeGoto (falseLabel);
3285 ast2iCode (tree->right,lvl+1);
3288 /*-----------------------------------------------------------------*/
3289 /* geniCodeInline - intermediate code for inline assembler */
3290 /*-----------------------------------------------------------------*/
3292 geniCodeInline (ast * tree)
3296 ic = newiCode (INLINEASM, NULL, NULL);
3297 IC_INLINE (ic) = tree->values.inlineasm;
3301 /*-----------------------------------------------------------------*/
3302 /* geniCodeArrayInit - intermediate code for array initializer */
3303 /*-----------------------------------------------------------------*/
3305 geniCodeArrayInit (ast * tree, operand *array)
3309 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3310 ic = newiCode (ARRAYINIT, array, NULL);
3311 IC_ARRAYILIST (ic) = tree->values.constlist;
3313 operand *left=newOperand(), *right=newOperand();
3314 left->type=right->type=SYMBOL;
3315 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3316 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3317 ic = newiCode (ARRAYINIT, left, right);
3322 /*-----------------------------------------------------------------*/
3323 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3324 /* particular case. Ie : assigning or dereferencing array or ptr */
3325 /*-----------------------------------------------------------------*/
3326 set * lvaluereqSet = NULL;
3327 typedef struct lvalItem
3334 /*-----------------------------------------------------------------*/
3335 /* addLvaluereq - add a flag for lvalreq for current ast level */
3336 /*-----------------------------------------------------------------*/
3337 void addLvaluereq(int lvl)
3339 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3342 addSetHead(&lvaluereqSet,lpItem);
3345 /*-----------------------------------------------------------------*/
3346 /* delLvaluereq - del a flag for lvalreq for current ast level */
3347 /*-----------------------------------------------------------------*/
3351 lpItem = getSet(&lvaluereqSet);
3352 if(lpItem) Safe_free(lpItem);
3354 /*-----------------------------------------------------------------*/
3355 /* clearLvaluereq - clear lvalreq flag */
3356 /*-----------------------------------------------------------------*/
3357 void clearLvaluereq()
3360 lpItem = peekSet(lvaluereqSet);
3361 if(lpItem) lpItem->req = 0;
3363 /*-----------------------------------------------------------------*/
3364 /* getLvaluereq - get the last lvalreq level */
3365 /*-----------------------------------------------------------------*/
3366 int getLvaluereqLvl()
3369 lpItem = peekSet(lvaluereqSet);
3370 if(lpItem) return lpItem->lvl;
3373 /*-----------------------------------------------------------------*/
3374 /* isLvaluereq - is lvalreq valid for this level ? */
3375 /*-----------------------------------------------------------------*/
3376 int isLvaluereq(int lvl)
3379 lpItem = peekSet(lvaluereqSet);
3380 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3384 /*-----------------------------------------------------------------*/
3385 /* ast2iCode - creates an icodeList from an ast */
3386 /*-----------------------------------------------------------------*/
3388 ast2iCode (ast * tree,int lvl)
3390 operand *left = NULL;
3391 operand *right = NULL;
3395 /* set the global variables for filename & line number */
3397 filename = tree->filename;
3399 lineno = tree->lineno;
3401 block = tree->block;
3403 scopeLevel = tree->level;
3405 if (tree->type == EX_VALUE)
3406 return operandFromValue (tree->opval.val);
3408 if (tree->type == EX_LINK)
3409 return operandFromLink (tree->opval.lnk);
3411 /* if we find a nullop */
3412 if (tree->type == EX_OP &&
3413 (tree->opval.op == NULLOP ||
3414 tree->opval.op == BLOCK))
3416 ast2iCode (tree->left,lvl+1);
3417 ast2iCode (tree->right,lvl+1);
3421 /* special cases for not evaluating */
3422 if (tree->opval.op != ':' &&
3423 tree->opval.op != '?' &&
3424 tree->opval.op != CALL &&
3425 tree->opval.op != IFX &&
3426 tree->opval.op != LABEL &&
3427 tree->opval.op != GOTO &&
3428 tree->opval.op != SWITCH &&
3429 tree->opval.op != FUNCTION &&
3430 tree->opval.op != INLINEASM)
3433 if (IS_ASSIGN_OP (tree->opval.op) ||
3434 IS_DEREF_OP (tree) ||
3435 (tree->opval.op == '&' && !tree->right) ||
3436 tree->opval.op == PTR_OP)
3439 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3440 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3443 left = operandFromAst (tree->left,lvl);
3445 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3446 left = geniCodeRValue (left, TRUE);
3450 left = operandFromAst (tree->left,lvl);
3452 if (tree->opval.op == INC_OP ||
3453 tree->opval.op == DEC_OP)
3456 right = operandFromAst (tree->right,lvl);
3461 right = operandFromAst (tree->right,lvl);
3465 /* now depending on the type of operand */
3466 /* this will be a biggy */
3467 switch (tree->opval.op)
3470 case '[': /* array operation */
3472 //sym_link *ltype = operandType (left);
3473 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3474 left = geniCodeRValue (left, FALSE);
3475 right = geniCodeRValue (right, TRUE);
3478 return geniCodeArray (left, right,lvl);
3480 case '.': /* structure dereference */
3481 if (IS_PTR (operandType (left)))
3482 left = geniCodeRValue (left, TRUE);
3484 left = geniCodeRValue (left, FALSE);
3486 return geniCodeStruct (left, right, tree->lvalue);
3488 case PTR_OP: /* structure pointer dereference */
3491 pType = operandType (left);
3492 left = geniCodeRValue (left, TRUE);
3494 setOClass (pType, getSpec (operandType (left)));
3497 return geniCodeStruct (left, right, tree->lvalue);
3499 case INC_OP: /* increment operator */
3501 return geniCodePostInc (left);
3503 return geniCodePreInc (right);
3505 case DEC_OP: /* decrement operator */
3507 return geniCodePostDec (left);
3509 return geniCodePreDec (right);
3511 case '&': /* bitwise and or address of operator */
3513 { /* this is a bitwise operator */
3514 left = geniCodeRValue (left, FALSE);
3515 right = geniCodeRValue (right, FALSE);
3516 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3519 return geniCodeAddressOf (left);
3521 case '|': /* bitwise or & xor */
3523 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3524 geniCodeRValue (right, FALSE),
3529 return geniCodeDivision (geniCodeRValue (left, FALSE),
3530 geniCodeRValue (right, FALSE));
3533 return geniCodeModulus (geniCodeRValue (left, FALSE),
3534 geniCodeRValue (right, FALSE));
3537 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3538 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3540 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3544 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3545 geniCodeRValue (right, FALSE));
3547 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3551 return geniCodeAdd (geniCodeRValue (left, FALSE),
3552 geniCodeRValue (right, FALSE),lvl);
3554 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3557 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3558 geniCodeRValue (right, FALSE));
3561 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3562 geniCodeRValue (right, FALSE));
3564 return geniCodeCast (operandType (left),
3565 geniCodeRValue (right, FALSE), FALSE);
3571 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3575 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3576 setOperandType (op, UCHARTYPE);
3587 return geniCodeLogic (geniCodeRValue (left, FALSE),
3588 geniCodeRValue (right, FALSE),
3591 return geniCodeConditional (tree,lvl);
3594 return operandFromLit (getSize (tree->right->ftype));
3598 sym_link *rtype = operandType (right);
3599 sym_link *ltype = operandType (left);
3600 if (IS_PTR (rtype) && IS_ITEMP (right)
3601 && right->isaddr && compareType (rtype->next, ltype) == 1)
3602 right = geniCodeRValue (right, TRUE);
3604 right = geniCodeRValue (right, FALSE);
3606 geniCodeAssign (left, right, 0);
3611 geniCodeAssign (left,
3612 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3614 geniCodeRValue (right, FALSE),FALSE), 0);
3618 geniCodeAssign (left,
3619 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3621 geniCodeRValue (right, FALSE)), 0);
3624 geniCodeAssign (left,
3625 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3627 geniCodeRValue (right, FALSE)), 0);
3630 sym_link *rtype = operandType (right);
3631 sym_link *ltype = operandType (left);
3632 if (IS_PTR (rtype) && IS_ITEMP (right)
3633 && right->isaddr && compareType (rtype->next, ltype) == 1)
3634 right = geniCodeRValue (right, TRUE);
3636 right = geniCodeRValue (right, FALSE);
3639 return geniCodeAssign (left,
3640 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3646 sym_link *rtype = operandType (right);
3647 sym_link *ltype = operandType (left);
3648 if (IS_PTR (rtype) && IS_ITEMP (right)
3649 && right->isaddr && compareType (rtype->next, ltype) == 1)
3651 right = geniCodeRValue (right, TRUE);
3655 right = geniCodeRValue (right, FALSE);
3658 geniCodeAssign (left,
3659 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3665 geniCodeAssign (left,
3666 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3668 geniCodeRValue (right, FALSE)), 0);
3671 geniCodeAssign (left,
3672 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3674 geniCodeRValue (right, FALSE)), 0);
3677 geniCodeAssign (left,
3678 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3680 geniCodeRValue (right, FALSE),
3682 operandType (left)), 0);
3685 geniCodeAssign (left,
3686 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3688 geniCodeRValue (right, FALSE),
3690 operandType (left)), 0);
3693 geniCodeAssign (left,
3694 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3696 geniCodeRValue (right, FALSE),
3698 operandType (left)), 0);
3700 return geniCodeRValue (right, FALSE);
3703 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3706 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3707 return ast2iCode (tree->right,lvl+1);
3710 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3711 return ast2iCode (tree->right,lvl+1);
3714 geniCodeFunctionBody (tree,lvl);
3718 geniCodeReturn (right);
3722 geniCodeIfx (tree,lvl);
3726 geniCodeSwitch (tree,lvl);
3730 geniCodeInline (tree);
3734 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3741 /*-----------------------------------------------------------------*/
3742 /* reverseICChain - gets from the list and creates a linkedlist */
3743 /*-----------------------------------------------------------------*/
3750 while ((loop = getSet (&iCodeChain)))
3762 /*-----------------------------------------------------------------*/
3763 /* iCodeFromAst - given an ast will convert it to iCode */
3764 /*-----------------------------------------------------------------*/
3766 iCodeFromAst (ast * tree)
3768 returnLabel = newiTempLabel ("_return");
3769 entryLabel = newiTempLabel ("_entry");
3771 return reverseiCChain ();