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)
822 wassert (IS_SYMOP(op));
827 isSymbolEqual (op->operand.symOperand, tval->sym))
834 /*-----------------------------------------------------------------*/
835 /* isOperandGlobal - return 1 if operand is a global variable */
836 /*-----------------------------------------------------------------*/
838 isOperandGlobal (operand * op)
847 (op->operand.symOperand->level == 0 ||
848 IS_STATIC (op->operand.symOperand->etype) ||
849 IS_EXTERN (op->operand.symOperand->etype))
856 /*-----------------------------------------------------------------*/
857 /* isOperandVolatile - return 1 if the operand is volatile */
858 /*-----------------------------------------------------------------*/
860 isOperandVolatile (operand * op, bool chkTemp)
865 if (IS_ITEMP (op) && !chkTemp)
868 opetype = getSpec (optype = operandType (op));
870 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
873 if (IS_VOLATILE (opetype))
878 /*-----------------------------------------------------------------*/
879 /* isOperandLiteral - returns 1 if an operand contains a literal */
880 /*-----------------------------------------------------------------*/
882 isOperandLiteral (operand * op)
889 opetype = getSpec (operandType (op));
891 if (IS_LITERAL (opetype))
897 /*-----------------------------------------------------------------*/
898 /* isOperandInFarSpace - will return true if operand is in farSpace */
899 /*-----------------------------------------------------------------*/
901 isOperandInFarSpace (operand * op)
911 if (!IS_TRUE_SYMOP (op))
914 etype = SPIL_LOC (op)->etype;
920 etype = getSpec (operandType (op));
922 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
925 /*------------------------------------------------------------------*/
926 /* isOperandInDirSpace - will return true if operand is in dirSpace */
927 /*------------------------------------------------------------------*/
929 isOperandInDirSpace (operand * op)
939 if (!IS_TRUE_SYMOP (op))
942 etype = SPIL_LOC (op)->etype;
948 etype = getSpec (operandType (op));
950 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
953 /*--------------------------------------------------------------------*/
954 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
955 /*--------------------------------------------------------------------*/
957 isOperandInCodeSpace (operand * op)
967 etype = getSpec (operandType (op));
969 if (!IS_TRUE_SYMOP (op))
972 etype = SPIL_LOC (op)->etype;
978 etype = getSpec (operandType (op));
980 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
983 /*-----------------------------------------------------------------*/
984 /* isOperandOnStack - will return true if operand is on stack */
985 /*-----------------------------------------------------------------*/
987 isOperandOnStack (operand * op)
997 etype = getSpec (operandType (op));
998 if (IN_STACK (etype) ||
999 OP_SYMBOL(op)->onStack ||
1000 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1006 /*-----------------------------------------------------------------*/
1007 /* operandLitValue - literal value of an operand */
1008 /*-----------------------------------------------------------------*/
1010 operandLitValue (operand * op)
1012 assert (isOperandLiteral (op));
1014 return floatFromVal (op->operand.valOperand);
1017 /*-----------------------------------------------------------------*/
1018 /* getBuiltInParms - returns parameters to a builtin functions */
1019 /*-----------------------------------------------------------------*/
1020 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1025 /* builtin functions uses only SEND for parameters */
1026 while (ic->op != CALL) {
1027 assert(ic->op == SEND && ic->builtinSEND);
1028 ic->generated = 1; /* mark the icode as generated */
1029 parms[*pcount] = IC_LEFT(ic);
1035 /* make sure this is a builtin function call */
1036 assert(IS_SYMOP(IC_LEFT(ic)));
1037 ftype = operandType(IC_LEFT(ic));
1038 assert(IFFUNC_ISBUILTIN(ftype));
1042 /*-----------------------------------------------------------------*/
1043 /* operandOperation - perforoms operations on operands */
1044 /*-----------------------------------------------------------------*/
1046 operandOperation (operand * left, operand * right,
1047 int op, sym_link * type)
1049 sym_link *let , *ret=NULL;
1050 operand *retval = (operand *) 0;
1052 assert (isOperandLiteral (left));
1053 let = getSpec(operandType(left));
1055 assert (isOperandLiteral (right));
1056 ret = getSpec(operandType(left));
1062 retval = operandFromValue (valCastLiteral (type,
1063 operandLitValue (left) +
1064 operandLitValue (right)));
1067 retval = operandFromValue (valCastLiteral (type,
1068 operandLitValue (left) -
1069 operandLitValue (right)));
1072 retval = operandFromValue (valCastLiteral (type,
1073 operandLitValue (left) *
1074 operandLitValue (right)));
1077 if ((unsigned long) operandLitValue (right) == 0)
1079 werror (E_DIVIDE_BY_ZERO);
1084 retval = operandFromValue (valCastLiteral (type,
1085 operandLitValue (left) /
1086 operandLitValue (right)));
1089 if ((unsigned long) operandLitValue (right) == 0) {
1090 werror (E_DIVIDE_BY_ZERO);
1094 retval = operandFromLit ((SPEC_USIGN(let) ?
1095 (unsigned long) operandLitValue (left) :
1096 (long) operandLitValue (left)) %
1098 (unsigned long) operandLitValue (right) :
1099 (long) operandLitValue (right)));
1103 retval = operandFromLit ((SPEC_USIGN(let) ?
1104 (unsigned long) operandLitValue (left) :
1105 (long) operandLitValue (left)) <<
1107 (unsigned long) operandLitValue (right) :
1108 (long) operandLitValue (right)));
1111 double lval = operandLitValue(left), rval = operandLitValue(right);
1113 switch ((SPEC_USIGN(let) ? 2 : 0) + (SPEC_USIGN(ret) ? 1 : 0))
1115 case 0: // left=unsigned right=unsigned
1116 res=(unsigned long)lval >> (unsigned long)rval;
1118 case 1: // left=unsigned right=signed
1119 res=(unsigned long)lval >> (signed long)rval;
1121 case 2: // left=signed right=unsigned
1122 res=(signed long)lval >> (unsigned long)rval;
1124 case 3: // left=signed right=signed
1125 res=(signed long)lval >> (signed long)rval;
1128 retval = operandFromLit (res);
1132 retval = operandFromLit (operandLitValue (left) ==
1133 operandLitValue (right));
1136 retval = operandFromLit (operandLitValue (left) <
1137 operandLitValue (right));
1140 retval = operandFromLit (operandLitValue (left) <=
1141 operandLitValue (right));
1144 retval = operandFromLit (operandLitValue (left) !=
1145 operandLitValue (right));
1148 retval = operandFromLit (operandLitValue (left) >
1149 operandLitValue (right));
1152 retval = operandFromLit (operandLitValue (left) >=
1153 operandLitValue (right));
1156 retval = operandFromLit ((long)operandLitValue(left) &
1157 (long)operandLitValue(right));
1160 retval = operandFromLit ((long)operandLitValue (left) |
1161 (long)operandLitValue (right));
1164 retval = operandFromLit ((long)operandLitValue (left) ^
1165 (long)operandLitValue (right));
1168 retval = operandFromLit (operandLitValue (left) &&
1169 operandLitValue (right));
1172 retval = operandFromLit (operandLitValue (left) ||
1173 operandLitValue (right));
1177 long i = (long) operandLitValue (left);
1179 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1185 long i = (long) operandLitValue (left);
1187 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1193 retval = operandFromLit (-1 * operandLitValue (left));
1197 retval = operandFromLit (~((long) operandLitValue (left)));
1201 retval = operandFromLit (!operandLitValue (left));
1205 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1206 " operandOperation invalid operator ");
1214 /*-----------------------------------------------------------------*/
1215 /* isOperandEqual - compares two operand & return 1 if they r = */
1216 /*-----------------------------------------------------------------*/
1218 isOperandEqual (operand * left, operand * right)
1220 /* if the pointers are equal then they are equal */
1224 /* if either of them null then false */
1225 if (!left || !right)
1228 if (left->type != right->type)
1231 if (IS_SYMOP (left) && IS_SYMOP (right))
1232 return left->key == right->key;
1234 /* if types are the same */
1238 return isSymbolEqual (left->operand.symOperand,
1239 right->operand.symOperand);
1241 return (floatFromVal (left->operand.valOperand) ==
1242 floatFromVal (right->operand.valOperand));
1244 if (compareType (left->operand.typeOperand,
1245 right->operand.typeOperand) == 1)
1252 /*-------------------------------------------------------------------*/
1253 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1254 /*-------------------------------------------------------------------*/
1256 isiCodeEqual (iCode * left, iCode * right)
1258 /* if the same pointer */
1262 /* if either of them null */
1263 if (!left || !right)
1266 /* if operand are the same */
1267 if (left->op == right->op)
1270 /* compare all the elements depending on type */
1271 if (left->op != IFX)
1273 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1275 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1281 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1283 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1285 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1294 /*-----------------------------------------------------------------*/
1295 /* newiTempFromOp - create a temp Operand with same attributes */
1296 /*-----------------------------------------------------------------*/
1298 newiTempFromOp (operand * op)
1308 nop = newiTempOperand (operandType (op), TRUE);
1309 nop->isaddr = op->isaddr;
1310 nop->isvolatile = op->isvolatile;
1311 nop->isGlobal = op->isGlobal;
1312 nop->isLiteral = op->isLiteral;
1313 nop->usesDefs = op->usesDefs;
1314 nop->isParm = op->isParm;
1318 /*-----------------------------------------------------------------*/
1319 /* operand from operand - creates an operand holder for the type */
1320 /*-----------------------------------------------------------------*/
1322 operandFromOperand (operand * op)
1328 nop = newOperand ();
1329 nop->type = op->type;
1330 nop->isaddr = op->isaddr;
1332 nop->isvolatile = op->isvolatile;
1333 nop->isGlobal = op->isGlobal;
1334 nop->isLiteral = op->isLiteral;
1335 nop->usesDefs = op->usesDefs;
1336 nop->isParm = op->isParm;
1341 nop->operand.symOperand = op->operand.symOperand;
1344 nop->operand.valOperand = op->operand.valOperand;
1347 nop->operand.typeOperand = op->operand.typeOperand;
1354 /*-----------------------------------------------------------------*/
1355 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1356 /*-----------------------------------------------------------------*/
1358 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1360 operand *nop = operandFromOperand (op);
1362 if (nop->type == SYMBOL)
1364 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1365 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1371 /*-----------------------------------------------------------------*/
1372 /* operandFromSymbol - creates an operand from a symbol */
1373 /*-----------------------------------------------------------------*/
1375 operandFromSymbol (symbol * sym)
1380 /* if the symbol's type is a literal */
1381 /* then it is an enumerator type */
1382 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1383 return operandFromValue (valFromType (sym->etype));
1386 sym->key = ++operandKey;
1388 /* if this an implicit variable, means struct/union */
1389 /* member so just return it */
1390 if (sym->implicit || IS_FUNC (sym->type))
1394 op->operand.symOperand = sym;
1396 op->isvolatile = isOperandVolatile (op, TRUE);
1397 op->isGlobal = isOperandGlobal (op);
1401 /* under the following conditions create a
1402 register equivalent for a local symbol */
1403 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1404 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1405 (!(options.model == MODEL_FLAT24)) ) &&
1406 options.stackAuto == 0)
1409 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1410 !IS_FUNC (sym->type) && /* not a function */
1411 !sym->_isparm && /* not a parameter */
1412 sym->level && /* is a local variable */
1413 !sym->addrtaken && /* whose address has not been taken */
1414 !sym->reqv && /* does not already have a reg equivalence */
1415 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1416 !IS_STATIC (sym->etype) && /* and not declared static */
1417 !sym->islbl && /* not a label */
1418 ok && /* farspace check */
1419 !IS_BITVAR (sym->etype) /* not a bit variable */
1423 /* we will use it after all optimizations
1424 and before liveRange calculation */
1425 sym->reqv = newiTempOperand (sym->type, 0);
1426 sym->reqv->key = sym->key;
1427 OP_SYMBOL (sym->reqv)->key = sym->key;
1428 OP_SYMBOL (sym->reqv)->isreqv = 1;
1429 OP_SYMBOL (sym->reqv)->islocal = 1;
1430 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1431 SPIL_LOC (sym->reqv) = sym;
1434 if (!IS_AGGREGATE (sym->type))
1438 op->operand.symOperand = sym;
1441 op->isvolatile = isOperandVolatile (op, TRUE);
1442 op->isGlobal = isOperandGlobal (op);
1443 op->isPtr = IS_PTR (operandType (op));
1444 op->isParm = sym->_isparm;
1449 /* itemp = &[_symbol] */
1451 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1452 IC_LEFT (ic)->type = SYMBOL;
1453 IC_LEFT (ic)->operand.symOperand = sym;
1454 IC_LEFT (ic)->key = sym->key;
1455 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1456 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1457 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1460 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1461 if (IS_ARRAY (sym->type))
1463 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1464 IC_RESULT (ic)->isaddr = 0;
1467 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1471 return IC_RESULT (ic);
1474 /*-----------------------------------------------------------------*/
1475 /* operandFromValue - creates an operand from value */
1476 /*-----------------------------------------------------------------*/
1478 operandFromValue (value * val)
1482 /* if this is a symbol then do the symbol thing */
1484 return operandFromSymbol (val->sym);
1486 /* this is not a symbol */
1489 op->operand.valOperand = val;
1490 op->isLiteral = isOperandLiteral (op);
1494 /*-----------------------------------------------------------------*/
1495 /* operandFromLink - operand from typeChain */
1496 /*-----------------------------------------------------------------*/
1498 operandFromLink (sym_link * type)
1502 /* operand from sym_link */
1508 op->operand.typeOperand = copyLinkChain (type);
1512 /*-----------------------------------------------------------------*/
1513 /* operandFromLit - makes an operand from a literal value */
1514 /*-----------------------------------------------------------------*/
1516 operandFromLit (double i)
1518 return operandFromValue (valueFromLit (i));
1521 /*-----------------------------------------------------------------*/
1522 /* operandFromAst - creates an operand from an ast */
1523 /*-----------------------------------------------------------------*/
1525 operandFromAst (ast * tree,int lvl)
1531 /* depending on type do */
1535 return ast2iCode (tree,lvl+1);
1539 return operandFromValue (tree->opval.val);
1543 return operandFromLink (tree->opval.lnk);
1547 /* Just to keep the comiler happy */
1548 return (operand *) 0;
1551 /*-----------------------------------------------------------------*/
1552 /* setOperandType - sets the operand's type to the given type */
1553 /*-----------------------------------------------------------------*/
1555 setOperandType (operand * op, sym_link * type)
1557 /* depending on the type of operand */
1562 op->operand.valOperand->etype =
1563 getSpec (op->operand.valOperand->type =
1564 copyLinkChain (type));
1568 if (op->operand.symOperand->isitmp)
1569 op->operand.symOperand->etype =
1570 getSpec (op->operand.symOperand->type =
1571 copyLinkChain (type));
1573 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1574 "attempt to modify type of source");
1578 op->operand.typeOperand = copyLinkChain (type);
1583 /*-----------------------------------------------------------------*/
1584 /* Get size in byte of ptr need to access an array */
1585 /*-----------------------------------------------------------------*/
1587 getArraySizePtr (operand * op)
1589 sym_link *ltype = operandType(op);
1593 int size = getSize(ltype);
1594 return(IS_GENPTR(ltype)?(size-1):size);
1599 sym_link *letype = getSpec(ltype);
1600 switch (PTR_TYPE (SPEC_OCLS (letype)))
1612 return (GPTRSIZE-1);
1621 /*-----------------------------------------------------------------*/
1622 /* perform "usual unary conversions" */
1623 /*-----------------------------------------------------------------*/
1625 usualUnaryConversions (operand * op)
1627 if (IS_INTEGRAL (operandType (op)))
1629 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1632 return geniCodeCast (INTTYPE, op, TRUE);
1638 /*-----------------------------------------------------------------*/
1639 /* perform "usual binary conversions" */
1640 /*-----------------------------------------------------------------*/
1642 usualBinaryConversions (operand ** op1, operand ** op2)
1645 sym_link *rtype = operandType (*op2);
1646 sym_link *ltype = operandType (*op1);
1648 ctype = computeType (ltype, rtype);
1650 *op1 = geniCodeCast (ctype, *op1, TRUE);
1651 *op2 = geniCodeCast (ctype, *op2, TRUE);
1656 /*-----------------------------------------------------------------*/
1657 /* geniCodeValueAtAddress - generate intermeditate code for value */
1659 /*-----------------------------------------------------------------*/
1661 geniCodeRValue (operand * op, bool force)
1664 sym_link *type = operandType (op);
1665 sym_link *etype = getSpec (type);
1667 /* if this is an array & already */
1668 /* an address then return this */
1669 if (IS_AGGREGATE (type) ||
1670 (IS_PTR (type) && !force && !op->isaddr))
1671 return operandFromOperand (op);
1673 /* if this is not an address then must be */
1674 /* rvalue already so return this one */
1678 /* if this is not a temp symbol then */
1679 if (!IS_ITEMP (op) &&
1681 !IN_FARSPACE (SPEC_OCLS (etype)))
1683 op = operandFromOperand (op);
1688 if (IS_SPEC (type) &&
1689 IS_TRUE_SYMOP (op) &&
1690 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1691 (options.model == MODEL_FLAT24) ))
1693 op = operandFromOperand (op);
1698 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1699 if (IS_PTR (type) && op->isaddr && force)
1702 type = copyLinkChain (type);
1704 IC_RESULT (ic) = newiTempOperand (type, 1);
1705 IC_RESULT (ic)->isaddr = 0;
1707 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1711 return IC_RESULT (ic);
1714 /*-----------------------------------------------------------------*/
1715 /* geniCodeCast - changes the value from one type to another */
1716 /*-----------------------------------------------------------------*/
1718 geniCodeCast (sym_link * type, operand * op, bool implicit)
1722 sym_link *opetype = getSpec (optype = operandType (op));
1726 /* one of them has size zero then error */
1727 if (IS_VOID (optype))
1729 werror (E_CAST_ZERO);
1733 /* if the operand is already the desired type then do nothing */
1734 if (compareType (type, optype) == 1)
1737 /* if this is a literal then just change the type & return */
1738 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1739 return operandFromValue (valCastLiteral (type,
1740 operandLitValue (op)));
1742 /* if casting to/from pointers, do some checking */
1743 if (IS_PTR(type)) { // to a pointer
1744 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1745 if (IS_INTEGRAL(optype)) {
1746 // maybe this is NULL, than it's ok.
1747 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1748 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1749 // no way to set the storage
1750 if (IS_LITERAL(optype)) {
1751 werror(E_LITERAL_GENERIC);
1754 werror(E_NONPTR2_GENPTR);
1757 } else if (implicit) {
1758 werror(W_INTEGRAL2PTR_NOCAST);
1763 // shouldn't do that with float, array or structure unless to void
1764 if (!IS_VOID(getSpec(type)) &&
1765 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1766 werror(E_INCOMPAT_TYPES);
1770 } else { // from a pointer to a pointer
1771 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1772 // if not a pointer to a function
1773 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1774 if (implicit) { // if not to generic, they have to match
1775 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1776 werror(E_INCOMPAT_PTYPES);
1783 } else { // to a non pointer
1784 if (IS_PTR(optype)) { // from a pointer
1785 if (implicit) { // sneaky
1786 if (IS_INTEGRAL(type)) {
1787 werror(W_PTR2INTEGRAL_NOCAST);
1789 } else { // shouldn't do that with float, array or structure
1790 werror(E_INCOMPAT_TYPES);
1797 printFromToType (optype, type);
1800 /* if they are the same size create an assignment */
1801 if (getSize (type) == getSize (optype) &&
1802 !IS_BITFIELD (type) &&
1804 !IS_FLOAT (optype) &&
1805 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1806 (!IS_SPEC (type) && !IS_SPEC (optype))))
1809 ic = newiCode ('=', NULL, op);
1810 IC_RESULT (ic) = newiTempOperand (type, 0);
1811 SPIL_LOC (IC_RESULT (ic)) =
1812 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1813 IC_RESULT (ic)->isaddr = 0;
1817 ic = newiCode (CAST, operandFromLink (type),
1818 geniCodeRValue (op, FALSE));
1820 IC_RESULT (ic) = newiTempOperand (type, 0);
1823 /* preserve the storage class & output class */
1824 /* of the original variable */
1825 restype = getSpec (operandType (IC_RESULT (ic)));
1826 if (!IS_LITERAL(opetype))
1827 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1828 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1831 return IC_RESULT (ic);
1834 /*-----------------------------------------------------------------*/
1835 /* geniCodeLabel - will create a Label */
1836 /*-----------------------------------------------------------------*/
1838 geniCodeLabel (symbol * label)
1842 ic = newiCodeLabelGoto (LABEL, label);
1846 /*-----------------------------------------------------------------*/
1847 /* geniCodeGoto - will create a Goto */
1848 /*-----------------------------------------------------------------*/
1850 geniCodeGoto (symbol * label)
1854 ic = newiCodeLabelGoto (GOTO, label);
1858 /*-----------------------------------------------------------------*/
1859 /* geniCodeMultiply - gen intermediate code for multiplication */
1860 /*-----------------------------------------------------------------*/
1862 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1869 /* if they are both literal then we know the result */
1870 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1871 return operandFromValue (valMult (left->operand.valOperand,
1872 right->operand.valOperand));
1874 if (IS_LITERAL(retype)) {
1875 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1878 resType = usualBinaryConversions (&left, &right);
1880 rtype = operandType (right);
1881 retype = getSpec (rtype);
1882 ltype = operandType (left);
1883 letype = getSpec (ltype);
1887 SPEC_NOUN(getSpec(resType))=V_INT;
1890 /* if the right is a literal & power of 2 */
1891 /* then make it a left shift */
1892 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1893 efficient in most cases than 2 bytes result = 2 bytes << literal
1894 if port has 1 byte muldiv */
1895 if (p2 && !IS_FLOAT (letype) &&
1896 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1897 (port->support.muldiv == 1)))
1899 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1901 /* LEFT_OP need same size for left and result, */
1902 left = geniCodeCast (resType, left, TRUE);
1903 ltype = operandType (left);
1905 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1909 ic = newiCode ('*', left, right); /* normal multiplication */
1910 /* if the size left or right > 1 then support routine */
1911 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1915 IC_RESULT (ic) = newiTempOperand (resType, 1);
1918 return IC_RESULT (ic);
1921 /*-----------------------------------------------------------------*/
1922 /* geniCodeDivision - gen intermediate code for division */
1923 /*-----------------------------------------------------------------*/
1925 geniCodeDivision (operand * left, operand * right)
1930 sym_link *rtype = operandType (right);
1931 sym_link *retype = getSpec (rtype);
1932 sym_link *ltype = operandType (left);
1933 sym_link *letype = getSpec (ltype);
1935 resType = usualBinaryConversions (&left, &right);
1937 /* if the right is a literal & power of 2
1938 and left is unsigned then make it a
1940 if (IS_LITERAL (retype) &&
1941 !IS_FLOAT (letype) &&
1942 SPEC_USIGN(letype) &&
1943 (p2 = powof2 ((unsigned long)
1944 floatFromVal (right->operand.valOperand)))) {
1945 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1949 ic = newiCode ('/', left, right); /* normal division */
1950 /* if the size left or right > 1 then support routine */
1951 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1954 IC_RESULT (ic) = newiTempOperand (resType, 0);
1957 return IC_RESULT (ic);
1959 /*-----------------------------------------------------------------*/
1960 /* geniCodeModulus - gen intermediate code for modulus */
1961 /*-----------------------------------------------------------------*/
1963 geniCodeModulus (operand * left, operand * right)
1969 /* if they are both literal then we know the result */
1970 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1971 return operandFromValue (valMod (left->operand.valOperand,
1972 right->operand.valOperand));
1974 resType = usualBinaryConversions (&left, &right);
1976 /* now they are the same size */
1977 ic = newiCode ('%', left, right);
1979 /* if the size left or right > 1 then support routine */
1980 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1982 IC_RESULT (ic) = newiTempOperand (resType, 0);
1985 return IC_RESULT (ic);
1988 /*-----------------------------------------------------------------*/
1989 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1990 /*-----------------------------------------------------------------*/
1992 geniCodePtrPtrSubtract (operand * left, operand * right)
1998 /* if they are both literals then */
1999 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2001 result = operandFromValue (valMinus (left->operand.valOperand,
2002 right->operand.valOperand));
2006 ic = newiCode ('-', left, right);
2008 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2012 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2016 // should we really do this? is this ANSI?
2017 return geniCodeDivision (result,
2018 operandFromLit (getSize (ltype->next)));
2021 /*-----------------------------------------------------------------*/
2022 /* geniCodeSubtract - generates code for subtraction */
2023 /*-----------------------------------------------------------------*/
2025 geniCodeSubtract (operand * left, operand * right)
2032 /* if they both pointers then */
2033 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2034 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2035 return geniCodePtrPtrSubtract (left, right);
2037 /* if they are both literal then we know the result */
2038 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2039 && left->isLiteral && right->isLiteral)
2040 return operandFromValue (valMinus (left->operand.valOperand,
2041 right->operand.valOperand));
2043 /* if left is an array or pointer */
2044 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2046 isarray = left->isaddr;
2047 right = geniCodeMultiply (right,
2048 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2049 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2052 { /* make them the same size */
2053 resType = usualBinaryConversions (&left, &right);
2056 ic = newiCode ('-', left, right);
2058 IC_RESULT (ic) = newiTempOperand (resType, 1);
2059 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2061 /* if left or right is a float */
2062 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2066 return IC_RESULT (ic);
2069 /*-----------------------------------------------------------------*/
2070 /* geniCodeAdd - generates iCode for addition */
2071 /*-----------------------------------------------------------------*/
2073 geniCodeAdd (operand * left, operand * right, int lvl)
2082 /* if left is an array then array access */
2083 if (IS_ARRAY (ltype))
2084 return geniCodeArray (left, right,lvl);
2087 /* if the right side is LITERAL zero */
2088 /* return the left side */
2089 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2092 /* if left is literal zero return right */
2093 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2096 /* if left is a pointer then size */
2097 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2099 isarray = left->isaddr;
2100 // there is no need to multiply with 1
2101 if (getSize(ltype->next)!=1) {
2102 size = operandFromLit (getSize (ltype->next));
2103 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2105 resType = copyLinkChain (ltype);
2108 { // make them the same size
2109 resType = usualBinaryConversions (&left, &right);
2112 /* if they are both literals then we know */
2113 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2114 && left->isLiteral && right->isLiteral)
2115 return operandFromValue (valPlus (valFromType (letype),
2116 valFromType (retype)));
2118 ic = newiCode ('+', left, right);
2120 IC_RESULT (ic) = newiTempOperand (resType, 1);
2121 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2123 /* if left or right is a float then support
2125 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2130 return IC_RESULT (ic);
2134 /*-----------------------------------------------------------------*/
2135 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2136 /*-----------------------------------------------------------------*/
2138 aggrToPtr (sym_link * type, bool force)
2144 if (IS_PTR (type) && !force)
2147 etype = getSpec (type);
2151 /* if the output class is generic */
2152 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2153 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2155 /* if the variable was declared a constant */
2156 /* then the pointer points to a constant */
2157 if (IS_CONSTANT (etype))
2158 DCL_PTR_CONST (ptype) = 1;
2160 /* the variable was volatile then pointer to volatile */
2161 if (IS_VOLATILE (etype))
2162 DCL_PTR_VOLATILE (ptype) = 1;
2166 /*-----------------------------------------------------------------*/
2167 /* geniCodeArray2Ptr - array to pointer */
2168 /*-----------------------------------------------------------------*/
2170 geniCodeArray2Ptr (operand * op)
2172 sym_link *optype = operandType (op);
2173 sym_link *opetype = getSpec (optype);
2175 /* set the pointer depending on the storage class */
2176 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2177 DCL_PTR_CONST (optype) = port->mem.code_ro;
2180 /* if the variable was declared a constant */
2181 /* then the pointer points to a constant */
2182 if (IS_CONSTANT (opetype))
2183 DCL_PTR_CONST (optype) = 1;
2185 /* the variable was volatile then pointer to volatile */
2186 if (IS_VOLATILE (opetype))
2187 DCL_PTR_VOLATILE (optype) = 1;
2193 /*-----------------------------------------------------------------*/
2194 /* geniCodeArray - array access */
2195 /*-----------------------------------------------------------------*/
2197 geniCodeArray (operand * left, operand * right,int lvl)
2200 sym_link *ltype = operandType (left);
2204 if (IS_PTR (ltype->next) && left->isaddr)
2206 left = geniCodeRValue (left, FALSE);
2208 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2211 right = geniCodeMultiply (right,
2212 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2214 /* we can check for limits here */
2215 if (isOperandLiteral (right) &&
2218 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2220 werror (E_ARRAY_BOUND);
2221 right = operandFromLit (0);
2224 ic = newiCode ('+', left, right);
2226 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2227 !IS_AGGREGATE (ltype->next) &&
2228 !IS_PTR (ltype->next))
2229 ? ltype : ltype->next), 0);
2231 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2233 return IC_RESULT (ic);
2236 /*-----------------------------------------------------------------*/
2237 /* geniCodeStruct - generates intermediate code for structres */
2238 /*-----------------------------------------------------------------*/
2240 geniCodeStruct (operand * left, operand * right, bool islval)
2243 sym_link *type = operandType (left);
2244 sym_link *etype = getSpec (type);
2246 symbol *element = getStructElement (SPEC_STRUCT (etype),
2247 right->operand.symOperand);
2249 wassert(IS_SYMOP(right));
2251 /* add the offset */
2252 ic = newiCode ('+', left, operandFromLit (element->offset));
2254 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2256 /* preserve the storage & output class of the struct */
2257 /* as well as the volatile attribute */
2258 retype = getSpec (operandType (IC_RESULT (ic)));
2259 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2260 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2261 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2263 if (IS_PTR (element->type))
2264 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2266 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2270 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2273 /*-----------------------------------------------------------------*/
2274 /* geniCodePostInc - generate int code for Post increment */
2275 /*-----------------------------------------------------------------*/
2277 geniCodePostInc (operand * op)
2281 sym_link *optype = operandType (op);
2283 operand *rv = (IS_ITEMP (op) ?
2284 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2286 sym_link *rvtype = operandType (rv);
2289 /* if this is not an address we have trouble */
2292 werror (E_LVALUE_REQUIRED, "++");
2296 rOp = newiTempOperand (rvtype, 0);
2297 OP_SYMBOL(rOp)->noSpilLoc = 1;
2300 OP_SYMBOL(rv)->noSpilLoc = 1;
2302 geniCodeAssign (rOp, rv, 0);
2304 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2305 if (IS_FLOAT (rvtype))
2306 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2308 ic = newiCode ('+', rv, operandFromLit (size));
2310 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2313 geniCodeAssign (op, result, 0);
2319 /*-----------------------------------------------------------------*/
2320 /* geniCodePreInc - generate code for preIncrement */
2321 /*-----------------------------------------------------------------*/
2323 geniCodePreInc (operand * op)
2326 sym_link *optype = operandType (op);
2327 operand *rop = (IS_ITEMP (op) ?
2328 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2330 sym_link *roptype = operandType (rop);
2336 werror (E_LVALUE_REQUIRED, "++");
2341 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2342 if (IS_FLOAT (roptype))
2343 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2345 ic = newiCode ('+', rop, operandFromLit (size));
2346 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2350 return geniCodeAssign (op, result, 0);
2353 /*-----------------------------------------------------------------*/
2354 /* geniCodePostDec - generates code for Post decrement */
2355 /*-----------------------------------------------------------------*/
2357 geniCodePostDec (operand * op)
2361 sym_link *optype = operandType (op);
2363 operand *rv = (IS_ITEMP (op) ?
2364 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2366 sym_link *rvtype = operandType (rv);
2369 /* if this is not an address we have trouble */
2372 werror (E_LVALUE_REQUIRED, "--");
2376 rOp = newiTempOperand (rvtype, 0);
2377 OP_SYMBOL(rOp)->noSpilLoc = 1;
2380 OP_SYMBOL(rv)->noSpilLoc = 1;
2382 geniCodeAssign (rOp, rv, 0);
2384 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2385 if (IS_FLOAT (rvtype))
2386 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2388 ic = newiCode ('-', rv, operandFromLit (size));
2390 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2393 geniCodeAssign (op, result, 0);
2399 /*-----------------------------------------------------------------*/
2400 /* geniCodePreDec - generate code for pre decrement */
2401 /*-----------------------------------------------------------------*/
2403 geniCodePreDec (operand * op)
2406 sym_link *optype = operandType (op);
2407 operand *rop = (IS_ITEMP (op) ?
2408 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2410 sym_link *roptype = operandType (rop);
2416 werror (E_LVALUE_REQUIRED, "--");
2421 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2422 if (IS_FLOAT (roptype))
2423 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2425 ic = newiCode ('-', rop, operandFromLit (size));
2426 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2430 return geniCodeAssign (op, result, 0);
2434 /*-----------------------------------------------------------------*/
2435 /* geniCodeBitwise - gen int code for bitWise operators */
2436 /*-----------------------------------------------------------------*/
2438 geniCodeBitwise (operand * left, operand * right,
2439 int oper, sym_link * resType)
2443 left = geniCodeCast (resType, left, TRUE);
2444 right = geniCodeCast (resType, right, TRUE);
2446 ic = newiCode (oper, left, right);
2447 IC_RESULT (ic) = newiTempOperand (resType, 0);
2450 return IC_RESULT (ic);
2453 /*-----------------------------------------------------------------*/
2454 /* geniCodeAddressOf - gens icode for '&' address of operator */
2455 /*-----------------------------------------------------------------*/
2457 geniCodeAddressOf (operand * op)
2461 sym_link *optype = operandType (op);
2462 sym_link *opetype = getSpec (optype);
2464 /* lvalue check already done in decorateType */
2465 /* this must be a lvalue */
2466 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2467 /* werror (E_LVALUE_REQUIRED,"&"); */
2472 p->class = DECLARATOR;
2474 /* set the pointer depending on the storage class */
2475 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2476 DCL_PTR_CONST (p) = port->mem.code_ro;
2478 /* make sure we preserve the const & volatile */
2479 if (IS_CONSTANT (opetype))
2480 DCL_PTR_CONST (p) = 1;
2482 if (IS_VOLATILE (opetype))
2483 DCL_PTR_VOLATILE (p) = 1;
2485 p->next = copyLinkChain (optype);
2487 /* if already a temp */
2490 setOperandType (op, p);
2495 /* other wise make this of the type coming in */
2496 ic = newiCode (ADDRESS_OF, op, NULL);
2497 IC_RESULT (ic) = newiTempOperand (p, 1);
2498 IC_RESULT (ic)->isaddr = 0;
2500 return IC_RESULT (ic);
2502 /*-----------------------------------------------------------------*/
2503 /* setOClass - sets the output class depending on the pointer type */
2504 /*-----------------------------------------------------------------*/
2506 setOClass (sym_link * ptr, sym_link * spec)
2508 switch (DCL_TYPE (ptr))
2511 SPEC_OCLS (spec) = data;
2515 SPEC_OCLS (spec) = generic;
2519 SPEC_OCLS (spec) = xdata;
2523 SPEC_OCLS (spec) = code;
2527 SPEC_OCLS (spec) = idata;
2531 SPEC_OCLS (spec) = xstack;
2535 SPEC_OCLS (spec) = eeprom;
2544 /*-----------------------------------------------------------------*/
2545 /* geniCodeDerefPtr - dereference pointer with '*' */
2546 /*-----------------------------------------------------------------*/
2548 geniCodeDerefPtr (operand * op,int lvl)
2550 sym_link *rtype, *retype;
2551 sym_link *optype = operandType (op);
2553 /* if this is a pointer then generate the rvalue */
2554 if (IS_PTR (optype))
2556 if (IS_TRUE_SYMOP (op))
2559 op = geniCodeRValue (op, TRUE);
2562 op = geniCodeRValue (op, TRUE);
2565 /* now get rid of the pointer part */
2566 if (isLvaluereq(lvl) && IS_ITEMP (op))
2568 retype = getSpec (rtype = copyLinkChain (optype));
2572 retype = getSpec (rtype = copyLinkChain (optype->next));
2575 /* if this is a pointer then outputclass needs 2b updated */
2576 if (IS_PTR (optype))
2577 setOClass (optype, retype);
2579 op->isGptr = IS_GENPTR (optype);
2581 /* if the pointer was declared as a constant */
2582 /* then we cannot allow assignment to the derefed */
2583 if (IS_PTR_CONST (optype))
2584 SPEC_CONST (retype) = 1;
2586 op->isaddr = (IS_PTR (rtype) ||
2587 IS_STRUCT (rtype) ||
2592 if (!isLvaluereq(lvl))
2593 op = geniCodeRValue (op, TRUE);
2595 setOperandType (op, rtype);
2600 /*-----------------------------------------------------------------*/
2601 /* geniCodeUnaryMinus - does a unary minus of the operand */
2602 /*-----------------------------------------------------------------*/
2604 geniCodeUnaryMinus (operand * op)
2607 sym_link *optype = operandType (op);
2609 if (IS_LITERAL (optype))
2610 return operandFromLit (-floatFromVal (op->operand.valOperand));
2612 ic = newiCode (UNARYMINUS, op, NULL);
2613 IC_RESULT (ic) = newiTempOperand (optype, 0);
2615 return IC_RESULT (ic);
2618 /*-----------------------------------------------------------------*/
2619 /* geniCodeLeftShift - gen i code for left shift */
2620 /*-----------------------------------------------------------------*/
2622 geniCodeLeftShift (operand * left, operand * right)
2626 ic = newiCode (LEFT_OP, left, right);
2627 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2629 return IC_RESULT (ic);
2632 /*-----------------------------------------------------------------*/
2633 /* geniCodeRightShift - gen i code for right shift */
2634 /*-----------------------------------------------------------------*/
2636 geniCodeRightShift (operand * left, operand * right)
2640 ic = newiCode (RIGHT_OP, left, right);
2641 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2643 return IC_RESULT (ic);
2646 /*-----------------------------------------------------------------*/
2647 /* geniCodeLogic- logic code */
2648 /*-----------------------------------------------------------------*/
2650 geniCodeLogic (operand * left, operand * right, int op)
2654 sym_link *rtype = operandType (right);
2655 sym_link *ltype = operandType (left);
2657 /* left is integral type and right is literal then
2658 check if the literal value is within bounds */
2659 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2661 checkConstantRange(ltype,
2662 OP_VALUE(right), "compare operation", 1);
2665 ctype = usualBinaryConversions (&left, &right);
2667 ic = newiCode (op, left, right);
2668 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2670 /* if comparing float
2671 and not a '==' || '!=' || '&&' || '||' (these
2673 if (IS_FLOAT(ctype) &&
2681 return IC_RESULT (ic);
2684 /*-----------------------------------------------------------------*/
2685 /* geniCodeUnary - for a a generic unary operation */
2686 /*-----------------------------------------------------------------*/
2688 geniCodeUnary (operand * op, int oper)
2690 iCode *ic = newiCode (oper, op, NULL);
2692 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2694 return IC_RESULT (ic);
2697 /*-----------------------------------------------------------------*/
2698 /* geniCodeConditional - geniCode for '?' ':' operation */
2699 /*-----------------------------------------------------------------*/
2701 geniCodeConditional (ast * tree,int lvl)
2704 symbol *falseLabel = newiTempLabel (NULL);
2705 symbol *exitLabel = newiTempLabel (NULL);
2706 operand *cond = ast2iCode (tree->left,lvl+1);
2707 operand *true, *false, *result;
2709 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2713 true = ast2iCode (tree->right->left,lvl+1);
2715 /* move the value to a new Operand */
2716 result = newiTempOperand (tree->right->ftype, 0);
2717 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2719 /* generate an unconditional goto */
2720 geniCodeGoto (exitLabel);
2722 /* now for the right side */
2723 geniCodeLabel (falseLabel);
2725 false = ast2iCode (tree->right->right,lvl+1);
2726 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2728 /* create the exit label */
2729 geniCodeLabel (exitLabel);
2734 /*-----------------------------------------------------------------*/
2735 /* geniCodeAssign - generate code for assignment */
2736 /*-----------------------------------------------------------------*/
2738 geniCodeAssign (operand * left, operand * right, int nosupdate)
2741 sym_link *ltype = operandType (left);
2742 sym_link *rtype = operandType (right);
2744 if (!left->isaddr && !IS_ITEMP (left))
2746 werror (E_LVALUE_REQUIRED, "assignment");
2750 /* left is integral type and right is literal then
2751 check if the literal value is within bounds */
2752 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2754 checkConstantRange(ltype,
2755 OP_VALUE(right), "= operation", 0);
2758 /* if the left & right type don't exactly match */
2759 /* if pointer set then make sure the check is
2760 done with the type & not the pointer */
2761 /* then cast rights type to left */
2763 /* first check the type for pointer assignement */
2764 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2765 compareType (ltype, rtype) <= 0)
2767 if (compareType (ltype->next, rtype) < 0)
2768 right = geniCodeCast (ltype->next, right, TRUE);
2770 else if (compareType (ltype, rtype) < 0)
2771 right = geniCodeCast (ltype, right, TRUE);
2773 /* if left is a true symbol & ! volatile
2774 create an assignment to temporary for
2775 the right & then assign this temporary
2776 to the symbol this is SSA . isn't it simple
2777 and folks have published mountains of paper on it */
2778 if (IS_TRUE_SYMOP (left) &&
2779 !isOperandVolatile (left, FALSE) &&
2780 isOperandGlobal (left))
2784 if (IS_TRUE_SYMOP (right))
2785 sym = OP_SYMBOL (right);
2786 ic = newiCode ('=', NULL, right);
2787 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2788 SPIL_LOC (right) = sym;
2792 ic = newiCode ('=', NULL, right);
2793 IC_RESULT (ic) = left;
2796 /* if left isgptr flag is set then support
2797 routine will be required */
2801 ic->nosupdate = nosupdate;
2805 /*-----------------------------------------------------------------*/
2806 /* geniCodeSEParms - generate code for side effecting fcalls */
2807 /*-----------------------------------------------------------------*/
2809 geniCodeSEParms (ast * parms,int lvl)
2814 if (parms->type == EX_OP && parms->opval.op == PARAM)
2816 geniCodeSEParms (parms->left,lvl);
2817 geniCodeSEParms (parms->right,lvl);
2821 /* hack don't like this but too lazy to think of
2823 if (IS_ADDRESS_OF_OP (parms))
2824 parms->left->lvalue = 1;
2826 if (IS_CAST_OP (parms) &&
2827 IS_PTR (parms->ftype) &&
2828 IS_ADDRESS_OF_OP (parms->right))
2829 parms->right->left->lvalue = 1;
2831 parms->opval.oprnd =
2832 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2834 parms->type = EX_OPERAND;
2835 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2836 SPEC_ARGREG(parms->ftype);
2839 /*-----------------------------------------------------------------*/
2840 /* geniCodeParms - generates parameters */
2841 /*-----------------------------------------------------------------*/
2843 geniCodeParms (ast * parms, value *argVals, int *stack,
2844 sym_link * fetype, symbol * func,int lvl)
2852 if (argVals==NULL) {
2854 argVals=FUNC_ARGS(func->type);
2857 /* if this is a param node then do the left & right */
2858 if (parms->type == EX_OP && parms->opval.op == PARAM)
2860 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2861 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2865 /* get the parameter value */
2866 if (parms->type == EX_OPERAND)
2867 pval = parms->opval.oprnd;
2870 /* maybe this else should go away ?? */
2871 /* hack don't like this but too lazy to think of
2873 if (IS_ADDRESS_OF_OP (parms))
2874 parms->left->lvalue = 1;
2876 if (IS_CAST_OP (parms) &&
2877 IS_PTR (parms->ftype) &&
2878 IS_ADDRESS_OF_OP (parms->right))
2879 parms->right->left->lvalue = 1;
2881 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2884 /* if register parm then make it a send */
2885 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2886 IFFUNC_ISBUILTIN(func->type))
2888 ic = newiCode (SEND, pval, NULL);
2889 ic->argreg = SPEC_ARGREG(parms->etype);
2890 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2895 /* now decide whether to push or assign */
2896 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2900 operand *top = operandFromSymbol (argVals->sym);
2901 /* clear useDef and other bitVectors */
2902 OP_USES_SET ((top), OP_DEFS_SET ((top), OP_SYMBOL(top)->clashes = NULL));
2903 geniCodeAssign (top, pval, 1);
2907 sym_link *p = operandType (pval);
2909 ic = newiCode (IPUSH, pval, NULL);
2911 /* update the stack adjustment */
2912 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2917 argVals=argVals->next;
2921 /*-----------------------------------------------------------------*/
2922 /* geniCodeCall - generates temp code for calling */
2923 /*-----------------------------------------------------------------*/
2925 geniCodeCall (operand * left, ast * parms,int lvl)
2929 sym_link *type, *etype;
2932 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2933 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2934 werror (E_FUNCTION_EXPECTED);
2938 /* take care of parameters with side-effecting
2939 function calls in them, this is required to take care
2940 of overlaying function parameters */
2941 geniCodeSEParms (parms,lvl);
2943 /* first the parameters */
2944 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2946 /* now call : if symbol then pcall */
2947 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
2948 ic = newiCode (PCALL, left, NULL);
2950 ic = newiCode (CALL, left, NULL);
2953 type = copyLinkChain (operandType (left)->next);
2954 etype = getSpec (type);
2955 SPEC_EXTR (etype) = 0;
2956 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2960 /* stack adjustment after call */
2961 ic->parmBytes = stack;
2966 /*-----------------------------------------------------------------*/
2967 /* geniCodeReceive - generate intermediate code for "receive" */
2968 /*-----------------------------------------------------------------*/
2970 geniCodeReceive (value * args)
2972 /* for all arguments that are passed in registers */
2976 if (IS_REGPARM (args->etype))
2978 operand *opr = operandFromValue (args);
2980 symbol *sym = OP_SYMBOL (opr);
2983 /* we will use it after all optimizations
2984 and before liveRange calculation */
2985 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2988 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2989 options.stackAuto == 0 &&
2990 (!(options.model == MODEL_FLAT24)) )
2995 opl = newiTempOperand (args->type, 0);
2997 sym->reqv->key = sym->key;
2998 OP_SYMBOL (sym->reqv)->key = sym->key;
2999 OP_SYMBOL (sym->reqv)->isreqv = 1;
3000 OP_SYMBOL (sym->reqv)->islocal = 0;
3001 SPIL_LOC (sym->reqv) = sym;
3005 ic = newiCode (RECEIVE, NULL, NULL);
3006 ic->argreg = SPEC_ARGREG(args->etype);
3008 currFunc->recvSize = getSize (sym->type);
3011 IC_RESULT (ic) = opr;
3019 /*-----------------------------------------------------------------*/
3020 /* geniCodeFunctionBody - create the function body */
3021 /*-----------------------------------------------------------------*/
3023 geniCodeFunctionBody (ast * tree,int lvl)
3030 /* reset the auto generation */
3036 func = ast2iCode (tree->left,lvl+1);
3037 fetype = getSpec (operandType (func));
3039 savelineno = lineno;
3040 lineno = OP_SYMBOL (func)->lineDef;
3041 /* create an entry label */
3042 geniCodeLabel (entryLabel);
3043 lineno = savelineno;
3045 /* create a proc icode */
3046 ic = newiCode (FUNCTION, func, NULL);
3047 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3051 /* for all parameters that are passed
3052 on registers add a "receive" */
3053 geniCodeReceive (tree->values.args);
3055 /* generate code for the body */
3056 ast2iCode (tree->right,lvl+1);
3058 /* create a label for return */
3059 geniCodeLabel (returnLabel);
3061 /* now generate the end proc */
3062 ic = newiCode (ENDFUNCTION, func, NULL);
3067 /*-----------------------------------------------------------------*/
3068 /* geniCodeReturn - gen icode for 'return' statement */
3069 /*-----------------------------------------------------------------*/
3071 geniCodeReturn (operand * op)
3075 /* if the operand is present force an rvalue */
3077 op = geniCodeRValue (op, FALSE);
3079 ic = newiCode (RETURN, op, NULL);
3083 /*-----------------------------------------------------------------*/
3084 /* geniCodeIfx - generates code for extended if statement */
3085 /*-----------------------------------------------------------------*/
3087 geniCodeIfx (ast * tree,int lvl)
3090 operand *condition = ast2iCode (tree->left,lvl+1);
3093 /* if condition is null then exit */
3097 condition = geniCodeRValue (condition, FALSE);
3099 cetype = getSpec (operandType (condition));
3100 /* if the condition is a literal */
3101 if (IS_LITERAL (cetype))
3103 if (floatFromVal (condition->operand.valOperand))
3105 if (tree->trueLabel)
3106 geniCodeGoto (tree->trueLabel);
3112 if (tree->falseLabel)
3113 geniCodeGoto (tree->falseLabel);
3120 if (tree->trueLabel)
3122 ic = newiCodeCondition (condition,
3127 if (tree->falseLabel)
3128 geniCodeGoto (tree->falseLabel);
3132 ic = newiCodeCondition (condition,
3139 ast2iCode (tree->right,lvl+1);
3142 /*-----------------------------------------------------------------*/
3143 /* geniCodeJumpTable - tries to create a jump table for switch */
3144 /*-----------------------------------------------------------------*/
3146 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3148 int min = 0, max = 0, t, cnt = 0;
3155 if (!tree || !caseVals)
3158 /* the criteria for creating a jump table is */
3159 /* all integer numbers between the maximum & minimum must */
3160 /* be present , the maximum value should not exceed 255 */
3161 min = max = (int) floatFromVal (vch = caseVals);
3162 SNPRINTF (buffer, sizeof(buffer),
3164 tree->values.switchVals.swNum,
3166 addSet (&labels, newiTempLabel (buffer));
3168 /* if there is only one case value then no need */
3169 if (!(vch = vch->next))
3174 if (((t = (int) floatFromVal (vch)) - max) != 1)
3176 SNPRINTF (buffer, sizeof(buffer),
3178 tree->values.switchVals.swNum,
3180 addSet (&labels, newiTempLabel (buffer));
3186 /* if the number of case statements <= 2 then */
3187 /* it is not economical to create the jump table */
3188 /* since two compares are needed for boundary conditions */
3189 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3192 if (tree->values.switchVals.swDefault)
3194 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3198 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3202 falseLabel = newiTempLabel (buffer);
3204 /* so we can create a jumptable */
3205 /* first we rule out the boundary conditions */
3206 /* if only optimization says so */
3207 if (!optimize.noJTabBoundary)
3209 sym_link *cetype = getSpec (operandType (cond));
3210 /* no need to check the lower bound if
3211 the condition is unsigned & minimum value is zero */
3212 if (!(min == 0 && SPEC_USIGN (cetype)))
3214 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3215 ic = newiCodeCondition (boundary, falseLabel, NULL);
3219 /* now for upper bounds */
3220 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3221 ic = newiCodeCondition (boundary, falseLabel, NULL);
3225 /* if the min is not zero then we no make it zero */
3228 cond = geniCodeSubtract (cond, operandFromLit (min));
3229 setOperandType (cond, UCHARTYPE);
3232 /* now create the jumptable */
3233 ic = newiCode (JUMPTABLE, NULL, NULL);
3234 IC_JTCOND (ic) = cond;
3235 IC_JTLABELS (ic) = labels;
3240 /*-----------------------------------------------------------------*/
3241 /* geniCodeSwitch - changes a switch to a if statement */
3242 /*-----------------------------------------------------------------*/
3244 geniCodeSwitch (ast * tree,int lvl)
3247 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3248 value *caseVals = tree->values.switchVals.swVals;
3249 symbol *trueLabel, *falseLabel;
3251 /* if we can make this a jump table */
3252 if (geniCodeJumpTable (cond, caseVals, tree))
3253 goto jumpTable; /* no need for the comparison */
3255 /* for the cases defined do */
3259 operand *compare = geniCodeLogic (cond,
3260 operandFromValue (caseVals),
3263 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3264 tree->values.switchVals.swNum,
3265 (int) floatFromVal (caseVals));
3266 trueLabel = newiTempLabel (buffer);
3268 ic = newiCodeCondition (compare, trueLabel, NULL);
3270 caseVals = caseVals->next;
3275 /* if default is present then goto break else break */
3276 if (tree->values.switchVals.swDefault)
3278 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3282 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3285 falseLabel = newiTempLabel (buffer);
3286 geniCodeGoto (falseLabel);
3289 ast2iCode (tree->right,lvl+1);
3292 /*-----------------------------------------------------------------*/
3293 /* geniCodeInline - intermediate code for inline assembler */
3294 /*-----------------------------------------------------------------*/
3296 geniCodeInline (ast * tree)
3300 ic = newiCode (INLINEASM, NULL, NULL);
3301 IC_INLINE (ic) = tree->values.inlineasm;
3305 /*-----------------------------------------------------------------*/
3306 /* geniCodeArrayInit - intermediate code for array initializer */
3307 /*-----------------------------------------------------------------*/
3309 geniCodeArrayInit (ast * tree, operand *array)
3313 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3314 ic = newiCode (ARRAYINIT, array, NULL);
3315 IC_ARRAYILIST (ic) = tree->values.constlist;
3317 operand *left=newOperand(), *right=newOperand();
3318 left->type=right->type=SYMBOL;
3319 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3320 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3321 ic = newiCode (ARRAYINIT, left, right);
3326 /*-----------------------------------------------------------------*/
3327 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3328 /* particular case. Ie : assigning or dereferencing array or ptr */
3329 /*-----------------------------------------------------------------*/
3330 set * lvaluereqSet = NULL;
3331 typedef struct lvalItem
3338 /*-----------------------------------------------------------------*/
3339 /* addLvaluereq - add a flag for lvalreq for current ast level */
3340 /*-----------------------------------------------------------------*/
3341 void addLvaluereq(int lvl)
3343 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3346 addSetHead(&lvaluereqSet,lpItem);
3349 /*-----------------------------------------------------------------*/
3350 /* delLvaluereq - del a flag for lvalreq for current ast level */
3351 /*-----------------------------------------------------------------*/
3355 lpItem = getSet(&lvaluereqSet);
3356 if(lpItem) Safe_free(lpItem);
3358 /*-----------------------------------------------------------------*/
3359 /* clearLvaluereq - clear lvalreq flag */
3360 /*-----------------------------------------------------------------*/
3361 void clearLvaluereq()
3364 lpItem = peekSet(lvaluereqSet);
3365 if(lpItem) lpItem->req = 0;
3367 /*-----------------------------------------------------------------*/
3368 /* getLvaluereq - get the last lvalreq level */
3369 /*-----------------------------------------------------------------*/
3370 int getLvaluereqLvl()
3373 lpItem = peekSet(lvaluereqSet);
3374 if(lpItem) return lpItem->lvl;
3377 /*-----------------------------------------------------------------*/
3378 /* isLvaluereq - is lvalreq valid for this level ? */
3379 /*-----------------------------------------------------------------*/
3380 int isLvaluereq(int lvl)
3383 lpItem = peekSet(lvaluereqSet);
3384 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3388 /*-----------------------------------------------------------------*/
3389 /* ast2iCode - creates an icodeList from an ast */
3390 /*-----------------------------------------------------------------*/
3392 ast2iCode (ast * tree,int lvl)
3394 operand *left = NULL;
3395 operand *right = NULL;
3399 /* set the global variables for filename & line number */
3401 filename = tree->filename;
3403 lineno = tree->lineno;
3405 block = tree->block;
3407 scopeLevel = tree->level;
3409 if (tree->type == EX_VALUE)
3410 return operandFromValue (tree->opval.val);
3412 if (tree->type == EX_LINK)
3413 return operandFromLink (tree->opval.lnk);
3415 /* if we find a nullop */
3416 if (tree->type == EX_OP &&
3417 (tree->opval.op == NULLOP ||
3418 tree->opval.op == BLOCK))
3420 ast2iCode (tree->left,lvl+1);
3421 ast2iCode (tree->right,lvl+1);
3425 /* special cases for not evaluating */
3426 if (tree->opval.op != ':' &&
3427 tree->opval.op != '?' &&
3428 tree->opval.op != CALL &&
3429 tree->opval.op != IFX &&
3430 tree->opval.op != LABEL &&
3431 tree->opval.op != GOTO &&
3432 tree->opval.op != SWITCH &&
3433 tree->opval.op != FUNCTION &&
3434 tree->opval.op != INLINEASM)
3437 if (IS_ASSIGN_OP (tree->opval.op) ||
3438 IS_DEREF_OP (tree) ||
3439 (tree->opval.op == '&' && !tree->right) ||
3440 tree->opval.op == PTR_OP)
3443 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3444 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3447 left = operandFromAst (tree->left,lvl);
3449 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3450 left = geniCodeRValue (left, TRUE);
3454 left = operandFromAst (tree->left,lvl);
3456 if (tree->opval.op == INC_OP ||
3457 tree->opval.op == DEC_OP)
3460 right = operandFromAst (tree->right,lvl);
3465 right = operandFromAst (tree->right,lvl);
3469 /* now depending on the type of operand */
3470 /* this will be a biggy */
3471 switch (tree->opval.op)
3474 case '[': /* array operation */
3476 //sym_link *ltype = operandType (left);
3477 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3478 left = geniCodeRValue (left, FALSE);
3479 right = geniCodeRValue (right, TRUE);
3482 return geniCodeArray (left, right,lvl);
3484 case '.': /* structure dereference */
3485 if (IS_PTR (operandType (left)))
3486 left = geniCodeRValue (left, TRUE);
3488 left = geniCodeRValue (left, FALSE);
3490 return geniCodeStruct (left, right, tree->lvalue);
3492 case PTR_OP: /* structure pointer dereference */
3495 pType = operandType (left);
3496 left = geniCodeRValue (left, TRUE);
3498 setOClass (pType, getSpec (operandType (left)));
3501 return geniCodeStruct (left, right, tree->lvalue);
3503 case INC_OP: /* increment operator */
3505 return geniCodePostInc (left);
3507 return geniCodePreInc (right);
3509 case DEC_OP: /* decrement operator */
3511 return geniCodePostDec (left);
3513 return geniCodePreDec (right);
3515 case '&': /* bitwise and or address of operator */
3517 { /* this is a bitwise operator */
3518 left = geniCodeRValue (left, FALSE);
3519 right = geniCodeRValue (right, FALSE);
3520 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3523 return geniCodeAddressOf (left);
3525 case '|': /* bitwise or & xor */
3527 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3528 geniCodeRValue (right, FALSE),
3533 return geniCodeDivision (geniCodeRValue (left, FALSE),
3534 geniCodeRValue (right, FALSE));
3537 return geniCodeModulus (geniCodeRValue (left, FALSE),
3538 geniCodeRValue (right, FALSE));
3541 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3542 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3544 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3548 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3549 geniCodeRValue (right, FALSE));
3551 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3555 return geniCodeAdd (geniCodeRValue (left, FALSE),
3556 geniCodeRValue (right, FALSE),lvl);
3558 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3561 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3562 geniCodeRValue (right, FALSE));
3565 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3566 geniCodeRValue (right, FALSE));
3568 return geniCodeCast (operandType (left),
3569 geniCodeRValue (right, FALSE), FALSE);
3575 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3579 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3580 setOperandType (op, UCHARTYPE);
3591 return geniCodeLogic (geniCodeRValue (left, FALSE),
3592 geniCodeRValue (right, FALSE),
3595 return geniCodeConditional (tree,lvl);
3598 return operandFromLit (getSize (tree->right->ftype));
3602 sym_link *rtype = operandType (right);
3603 sym_link *ltype = operandType (left);
3604 if (IS_PTR (rtype) && IS_ITEMP (right)
3605 && right->isaddr && compareType (rtype->next, ltype) == 1)
3606 right = geniCodeRValue (right, TRUE);
3608 right = geniCodeRValue (right, FALSE);
3610 geniCodeAssign (left, right, 0);
3615 geniCodeAssign (left,
3616 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3618 geniCodeRValue (right, FALSE),FALSE), 0);
3622 geniCodeAssign (left,
3623 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3625 geniCodeRValue (right, FALSE)), 0);
3628 geniCodeAssign (left,
3629 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3631 geniCodeRValue (right, FALSE)), 0);
3634 sym_link *rtype = operandType (right);
3635 sym_link *ltype = operandType (left);
3636 if (IS_PTR (rtype) && IS_ITEMP (right)
3637 && right->isaddr && compareType (rtype->next, ltype) == 1)
3638 right = geniCodeRValue (right, TRUE);
3640 right = geniCodeRValue (right, FALSE);
3643 return geniCodeAssign (left,
3644 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3650 sym_link *rtype = operandType (right);
3651 sym_link *ltype = operandType (left);
3652 if (IS_PTR (rtype) && IS_ITEMP (right)
3653 && right->isaddr && compareType (rtype->next, ltype) == 1)
3655 right = geniCodeRValue (right, TRUE);
3659 right = geniCodeRValue (right, FALSE);
3662 geniCodeAssign (left,
3663 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3669 geniCodeAssign (left,
3670 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3672 geniCodeRValue (right, FALSE)), 0);
3675 geniCodeAssign (left,
3676 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3678 geniCodeRValue (right, FALSE)), 0);
3681 geniCodeAssign (left,
3682 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3684 geniCodeRValue (right, FALSE),
3686 operandType (left)), 0);
3689 geniCodeAssign (left,
3690 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3692 geniCodeRValue (right, FALSE),
3694 operandType (left)), 0);
3697 geniCodeAssign (left,
3698 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3700 geniCodeRValue (right, FALSE),
3702 operandType (left)), 0);
3704 return geniCodeRValue (right, FALSE);
3707 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3710 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3711 return ast2iCode (tree->right,lvl+1);
3714 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3715 return ast2iCode (tree->right,lvl+1);
3718 geniCodeFunctionBody (tree,lvl);
3722 geniCodeReturn (right);
3726 geniCodeIfx (tree,lvl);
3730 geniCodeSwitch (tree,lvl);
3734 geniCodeInline (tree);
3738 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3745 /*-----------------------------------------------------------------*/
3746 /* reverseICChain - gets from the list and creates a linkedlist */
3747 /*-----------------------------------------------------------------*/
3754 while ((loop = getSet (&iCodeChain)))
3766 /*-----------------------------------------------------------------*/
3767 /* iCodeFromAst - given an ast will convert it to iCode */
3768 /*-----------------------------------------------------------------*/
3770 iCodeFromAst (ast * tree)
3772 returnLabel = newiTempLabel ("_return");
3773 entryLabel = newiTempLabel ("_entry");
3775 return reverseiCChain ();
3778 static const char *opTypeToStr(OPTYPE op)
3782 case SYMBOL: return "symbol";
3783 case VALUE: return "value";
3784 case TYPE: return "type";
3786 return "undefined type";
3790 operand *validateOpType(operand *op,
3797 if (op && op->type == type)
3802 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
3803 " expected %s, got %s\n",
3804 macro, args, file, line,
3805 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
3807 return op; // never reached, makes compiler happy.