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);
70 PRINTFUNC (picDummyRead);
72 iCodeTable codeTable[] =
74 {'!', "not", picGenericOne, NULL},
75 {'~', "~", picGenericOne, NULL},
76 {RRC, "rrc", picGenericOne, NULL},
77 {RLC, "rlc", picGenericOne, NULL},
78 {GETHBIT, "ghbit", picGenericOne, NULL},
79 {UNARYMINUS, "-", picGenericOne, NULL},
80 {IPUSH, "push", picGenericOne, NULL},
81 {IPOP, "pop", picGenericOne, NULL},
82 {CALL, "call", picGenericOne, NULL},
83 {PCALL, "pcall", picGenericOne, NULL},
84 {FUNCTION, "proc", picGenericOne, NULL},
85 {ENDFUNCTION, "eproc", picGenericOne, NULL},
86 {RETURN, "ret", picGenericOne, NULL},
87 {'+', "+", picGeneric, NULL},
88 {'-', "-", picGeneric, NULL},
89 {'*', "*", picGeneric, NULL},
90 {'/', "/", picGeneric, NULL},
91 {'%', "%", picGeneric, NULL},
92 {'>', ">", picGeneric, NULL},
93 {'<', "<", picGeneric, NULL},
94 {LE_OP, "<=", picGeneric, NULL},
95 {GE_OP, ">=", picGeneric, NULL},
96 {EQ_OP, "==", picGeneric, NULL},
97 {NE_OP, "!=", picGeneric, NULL},
98 {AND_OP, "&&", picGeneric, NULL},
99 {OR_OP, "||", picGeneric, NULL},
100 {'^', "^", picGeneric, NULL},
101 {'|', "|", picGeneric, NULL},
102 {BITWISEAND, "&", picGeneric, NULL},
103 {LEFT_OP, "<<", picGeneric, NULL},
104 {RIGHT_OP, ">>", picGeneric, NULL},
105 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
106 {ADDRESS_OF, "&", picAddrOf, NULL},
107 {CAST, "<>", picCast, NULL},
108 {'=', ":=", picAssign, NULL},
109 {LABEL, "", picLabel, NULL},
110 {GOTO, "", picGoto, NULL},
111 {JUMPTABLE, "jtab", picJumpTable, NULL},
112 {IFX, "if", picIfx, NULL},
113 {INLINEASM, "", picInline, NULL},
114 {RECEIVE, "recv", picReceive, NULL},
115 {SEND, "send", picGenericOne, NULL},
116 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
117 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL}
120 /*-----------------------------------------------------------------*/
121 /* checkConstantRange: check a constant against the type */
122 /*-----------------------------------------------------------------*/
124 /* pedantic=0: allmost anything is allowed as long as the absolute
125 value is within the bit range of the type, and -1 is treated as
126 0xf..f for unsigned types (e.g. in assign)
127 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
128 pedantic>1: "char c=200" is not allowed (evaluates to -56)
131 void checkConstantRange(sym_link *ltype, value *val, char *msg,
138 max = pow ((double)2.0, (double)bitsForType(ltype));
140 if (SPEC_LONG(val->type)) {
141 if (SPEC_USIGN(val->type)) {
142 v=SPEC_CVAL(val->type).v_ulong;
144 v=SPEC_CVAL(val->type).v_long;
147 if (SPEC_USIGN(val->type)) {
148 v=SPEC_CVAL(val->type).v_uint;
150 v=SPEC_CVAL(val->type).v_int;
156 // this could be a good idea
157 if (options.pedantic)
161 if (SPEC_NOUN(ltype)==FLOAT) {
166 if (!SPEC_USIGN(val->type) && v<0) {
168 if (SPEC_USIGN(ltype) && (pedantic>1)) {
174 // if very pedantic: "char c=200" is not allowed
175 if (pedantic>1 && !SPEC_USIGN(ltype)) {
176 max = max/2 + negative;
183 #if 0 // temporary disabled, leaving the warning as a reminder
185 SNPRINTF (message, sizeof(message), "for %s %s in %s",
186 SPEC_USIGN(ltype) ? "unsigned" : "signed",
187 nounName(ltype), msg);
188 werror (W_CONST_RANGE, message);
196 /*-----------------------------------------------------------------*/
197 /* operandName - returns the name of the operand */
198 /*-----------------------------------------------------------------*/
200 printOperand (operand * op, FILE * file)
217 opetype = getSpec (operandType (op));
218 if (SPEC_NOUN (opetype) == V_FLOAT)
219 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
221 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
222 printTypeChain (operandType (op), file);
229 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}" , */
230 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
232 OP_LIVEFROM (op), OP_LIVETO (op),
233 OP_SYMBOL (op)->stack,
234 op->isaddr, OP_SYMBOL (op)->isreqv,
235 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
236 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
240 printTypeChain (operandType (op), file);
241 if (SPIL_LOC (op) && IS_ITEMP (op))
242 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
247 /* if assigned to registers */
248 if (OP_SYMBOL (op)->nRegs)
250 if (OP_SYMBOL (op)->isspilt)
252 if (!OP_SYMBOL (op)->remat)
253 if (OP_SYMBOL (op)->usl.spillLoc)
254 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
255 OP_SYMBOL (op)->usl.spillLoc->rname :
256 OP_SYMBOL (op)->usl.spillLoc->name));
258 fprintf (file, "[err]");
260 fprintf (file, "[remat]");
266 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
267 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
272 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
273 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
274 /* if assigned to registers */
275 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
279 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
280 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
281 OP_SYMBOL (op)->regs[i]->name :
290 printTypeChain (op->operand.typeOperand, file);
296 fprintf (file, "\n");
301 /*-----------------------------------------------------------------*/
302 /* print functions */
303 /*-----------------------------------------------------------------*/
304 PRINTFUNC (picGetValueAtAddr)
307 printOperand (IC_RESULT (ic), of);
310 printOperand (IC_LEFT (ic), of);
316 PRINTFUNC (picSetValueAtAddr)
320 printOperand (IC_LEFT (ic), of);
321 fprintf (of, "] = ");
322 printOperand (IC_RIGHT (ic), of);
326 PRINTFUNC (picAddrOf)
329 printOperand (IC_RESULT (ic), of);
330 if (IS_ITEMP (IC_LEFT (ic)))
333 fprintf (of, " = &[");
334 printOperand (IC_LEFT (ic), of);
337 if (IS_ITEMP (IC_LEFT (ic)))
338 fprintf (of, " offsetAdd ");
341 printOperand (IC_RIGHT (ic), of);
343 if (IS_ITEMP (IC_LEFT (ic)))
349 PRINTFUNC (picJumpTable)
354 fprintf (of, "%s\t", s);
355 printOperand (IC_JTCOND (ic), of);
357 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
358 sym = setNextItem (IC_JTLABELS (ic)))
359 fprintf (of, "\t\t\t%s\n", sym->name);
362 PRINTFUNC (picGeneric)
365 printOperand (IC_RESULT (ic), of);
367 printOperand (IC_LEFT (ic), of);
368 fprintf (of, " %s ", s);
369 printOperand (IC_RIGHT (ic), of);
373 PRINTFUNC (picGenericOne)
378 printOperand (IC_RESULT (ic), of);
384 fprintf (of, "%s ", s);
385 printOperand (IC_LEFT (ic), of);
388 if (!IC_RESULT (ic) && !IC_LEFT (ic))
391 if (ic->op == SEND || ic->op == RECEIVE) {
392 fprintf(of,"{argreg = %d}",ic->argreg);
400 printOperand (IC_RESULT (ic), of);
402 printOperand (IC_LEFT (ic), of);
403 printOperand (IC_RIGHT (ic), of);
408 PRINTFUNC (picAssign)
412 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
415 printOperand (IC_RESULT (ic), of);
417 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
420 fprintf (of, " %s ", s);
421 printOperand (IC_RIGHT (ic), of);
428 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
434 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
441 printOperand (IC_COND (ic), of);
444 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
447 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
449 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
453 PRINTFUNC (picInline)
455 fprintf (of, "%s", IC_INLINE (ic));
458 PRINTFUNC (picReceive)
460 printOperand (IC_RESULT (ic), of);
461 fprintf (of, " = %s ", s);
462 printOperand (IC_LEFT (ic), of);
466 PRINTFUNC (picDummyRead)
469 fprintf (of, "%s ", s);
470 printOperand (IC_RIGHT (ic), of);
474 /*-----------------------------------------------------------------*/
475 /* piCode - prints one iCode */
476 /*-----------------------------------------------------------------*/
478 piCode (void *item, FILE * of)
486 icTab = getTableEntry (ic->op);
487 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
488 ic->filename, ic->lineno,
489 ic->seq, ic->key, ic->depth, ic->supportRtn);
490 icTab->iCodePrint (of, ic, icTab->printName);
496 printiCChain(ic,stdout);
498 /*-----------------------------------------------------------------*/
499 /* printiCChain - prints intermediate code for humans */
500 /*-----------------------------------------------------------------*/
502 printiCChain (iCode * icChain, FILE * of)
509 for (loop = icChain; loop; loop = loop->next)
511 if ((icTab = getTableEntry (loop->op)))
513 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
514 loop->filename, loop->lineno,
515 loop->seq, loop->key, loop->depth, loop->supportRtn);
517 icTab->iCodePrint (of, loop, icTab->printName);
523 /*-----------------------------------------------------------------*/
524 /* newOperand - allocate, init & return a new iCode */
525 /*-----------------------------------------------------------------*/
531 op = Safe_alloc ( sizeof (operand));
537 /*-----------------------------------------------------------------*/
538 /* newiCode - create and return a new iCode entry initialised */
539 /*-----------------------------------------------------------------*/
541 newiCode (int op, operand * left, operand * right)
545 ic = Safe_alloc ( sizeof (iCode));
548 ic->filename = filename;
550 ic->level = scopeLevel;
552 ic->key = iCodeKey++;
554 IC_RIGHT (ic) = right;
559 /*-----------------------------------------------------------------*/
560 /* newiCode for conditional statements */
561 /*-----------------------------------------------------------------*/
563 newiCodeCondition (operand * condition,
569 if (IS_VOID(operandType(condition))) {
570 werror(E_VOID_VALUE_USED);
573 ic = newiCode (IFX, NULL, NULL);
574 IC_COND (ic) = condition;
575 IC_TRUE (ic) = trueLabel;
576 IC_FALSE (ic) = falseLabel;
580 /*-----------------------------------------------------------------*/
581 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
582 /*-----------------------------------------------------------------*/
584 newiCodeLabelGoto (int op, symbol * label)
588 ic = newiCode (op, NULL, NULL);
592 IC_RIGHT (ic) = NULL;
593 IC_RESULT (ic) = NULL;
597 /*-----------------------------------------------------------------*/
598 /* newiTemp - allocate & return a newItemp Variable */
599 /*-----------------------------------------------------------------*/
607 SNPRINTF (buffer, sizeof(buffer), "%s", s);
611 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
614 itmp = newSymbol (buffer, 1);
615 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
621 /*-----------------------------------------------------------------*/
622 /* newiTempLabel - creates a temp variable label */
623 /*-----------------------------------------------------------------*/
625 newiTempLabel (char *s)
629 /* check if this alredy exists */
630 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
635 itmplbl = newSymbol (s, 1);
639 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
640 itmplbl = newSymbol (buffer, 1);
645 itmplbl->key = labelKey++;
646 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
650 /*-----------------------------------------------------------------*/
651 /* newiTempPreheaderLabel - creates a new preheader label */
652 /*-----------------------------------------------------------------*/
654 newiTempPreheaderLabel ()
658 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
659 itmplbl = newSymbol (buffer, 1);
663 itmplbl->key = labelKey++;
664 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
669 /*-----------------------------------------------------------------*/
670 /* initiCode - initialises some iCode related stuff */
671 /*-----------------------------------------------------------------*/
678 /*-----------------------------------------------------------------*/
679 /* copyiCode - make a copy of the iCode given */
680 /*-----------------------------------------------------------------*/
682 copyiCode (iCode * ic)
684 iCode *nic = newiCode (ic->op, NULL, NULL);
686 nic->lineno = ic->lineno;
687 nic->filename = ic->filename;
688 nic->block = ic->block;
689 nic->level = ic->level;
690 nic->parmBytes = ic->parmBytes;
692 /* deal with the special cases first */
696 IC_COND (nic) = operandFromOperand (IC_COND (ic));
697 IC_TRUE (nic) = IC_TRUE (ic);
698 IC_FALSE (nic) = IC_FALSE (ic);
702 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
703 IC_JTLABELS (nic) = IC_JTLABELS (ic);
708 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
709 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
713 IC_INLINE (nic) = IC_INLINE (ic);
717 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
721 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
722 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
723 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
729 /*-----------------------------------------------------------------*/
730 /* getTableEntry - gets the table entry for the given operator */
731 /*-----------------------------------------------------------------*/
733 getTableEntry (int oper)
737 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
738 if (oper == codeTable[i].icode)
739 return &codeTable[i];
744 /*-----------------------------------------------------------------*/
745 /* newiTempOperand - new intermediate temp operand */
746 /*-----------------------------------------------------------------*/
748 newiTempOperand (sym_link * type, char throwType)
751 operand *op = newOperand ();
755 itmp = newiTemp (NULL);
757 etype = getSpec (type);
759 if (IS_LITERAL (etype))
762 /* copy the type information */
764 itmp->etype = getSpec (itmp->type = (throwType ? type :
765 copyLinkChain (type)));
766 if (IS_LITERAL (itmp->etype))
768 SPEC_SCLS (itmp->etype) = S_REGISTER;
769 SPEC_OCLS (itmp->etype) = reg;
772 op->operand.symOperand = itmp;
773 op->key = itmp->key = ++operandKey;
777 /*-----------------------------------------------------------------*/
778 /* operandType - returns the type chain for an operand */
779 /*-----------------------------------------------------------------*/
781 operandType (operand * op)
783 /* depending on type of operand */
788 return op->operand.valOperand->type;
791 return op->operand.symOperand->type;
794 return op->operand.typeOperand;
796 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
797 " operand type not known ");
798 assert (0); /* should never come here */
799 /* Just to keep the compiler happy */
800 return (sym_link *) 0;
804 /*-----------------------------------------------------------------*/
805 /* isParamterToCall - will return 1 if op is a parameter to args */
806 /*-----------------------------------------------------------------*/
808 isParameterToCall (value * args, operand * op)
812 wassert (IS_SYMOP(op));
817 isSymbolEqual (op->operand.symOperand, tval->sym))
824 /*-----------------------------------------------------------------*/
825 /* isOperandGlobal - return 1 if operand is a global variable */
826 /*-----------------------------------------------------------------*/
828 isOperandGlobal (operand * op)
837 (op->operand.symOperand->level == 0 ||
838 IS_STATIC (op->operand.symOperand->etype) ||
839 IS_EXTERN (op->operand.symOperand->etype))
846 /*-----------------------------------------------------------------*/
847 /* isOperandVolatile - return 1 if the operand is volatile */
848 /*-----------------------------------------------------------------*/
850 isOperandVolatile (operand * op, bool chkTemp)
855 if (IS_ITEMP (op) && !chkTemp)
858 opetype = getSpec (optype = operandType (op));
860 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
863 if (IS_VOLATILE (opetype))
868 /*-----------------------------------------------------------------*/
869 /* isOperandLiteral - returns 1 if an operand contains a literal */
870 /*-----------------------------------------------------------------*/
872 isOperandLiteral (operand * op)
879 opetype = getSpec (operandType (op));
881 if (IS_LITERAL (opetype))
887 /*-----------------------------------------------------------------*/
888 /* isOperandInFarSpace - will return true if operand is in farSpace */
889 /*-----------------------------------------------------------------*/
891 isOperandInFarSpace (operand * op)
901 if (!IS_TRUE_SYMOP (op))
904 etype = SPIL_LOC (op)->etype;
910 etype = getSpec (operandType (op));
912 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
915 /*------------------------------------------------------------------*/
916 /* isOperandInDirSpace - will return true if operand is in dirSpace */
917 /*------------------------------------------------------------------*/
919 isOperandInDirSpace (operand * op)
929 if (!IS_TRUE_SYMOP (op))
932 etype = SPIL_LOC (op)->etype;
938 etype = getSpec (operandType (op));
940 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
943 /*--------------------------------------------------------------------*/
944 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
945 /*--------------------------------------------------------------------*/
947 isOperandInCodeSpace (operand * op)
957 etype = getSpec (operandType (op));
959 if (!IS_TRUE_SYMOP (op))
962 etype = SPIL_LOC (op)->etype;
968 etype = getSpec (operandType (op));
970 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
973 /*-----------------------------------------------------------------*/
974 /* isOperandOnStack - will return true if operand is on stack */
975 /*-----------------------------------------------------------------*/
977 isOperandOnStack (operand * op)
987 etype = getSpec (operandType (op));
988 if (IN_STACK (etype) ||
989 OP_SYMBOL(op)->onStack ||
990 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
996 /*-----------------------------------------------------------------*/
997 /* operandLitValue - literal value of an operand */
998 /*-----------------------------------------------------------------*/
1000 operandLitValue (operand * op)
1002 assert (isOperandLiteral (op));
1004 return floatFromVal (op->operand.valOperand);
1007 /*-----------------------------------------------------------------*/
1008 /* getBuiltInParms - returns parameters to a builtin functions */
1009 /*-----------------------------------------------------------------*/
1010 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1015 /* builtin functions uses only SEND for parameters */
1016 while (ic->op != CALL) {
1017 assert(ic->op == SEND && ic->builtinSEND);
1018 ic->generated = 1; /* mark the icode as generated */
1019 parms[*pcount] = IC_LEFT(ic);
1025 /* make sure this is a builtin function call */
1026 assert(IS_SYMOP(IC_LEFT(ic)));
1027 ftype = operandType(IC_LEFT(ic));
1028 assert(IFFUNC_ISBUILTIN(ftype));
1032 /*-----------------------------------------------------------------*/
1033 /* operandOperation - perforoms operations on operands */
1034 /*-----------------------------------------------------------------*/
1036 operandOperation (operand * left, operand * right,
1037 int op, sym_link * type)
1039 sym_link *let , *ret=NULL;
1040 operand *retval = (operand *) 0;
1042 assert (isOperandLiteral (left));
1043 let = getSpec(operandType(left));
1045 assert (isOperandLiteral (right));
1046 ret = getSpec(operandType(right));
1052 retval = operandFromValue (valCastLiteral (type,
1053 operandLitValue (left) +
1054 operandLitValue (right)));
1057 retval = operandFromValue (valCastLiteral (type,
1058 operandLitValue (left) -
1059 operandLitValue (right)));
1062 retval = operandFromValue (valCastLiteral (type,
1063 operandLitValue (left) *
1064 operandLitValue (right)));
1067 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1069 werror (E_DIVIDE_BY_ZERO);
1074 retval = operandFromValue (valCastLiteral (type,
1075 operandLitValue (left) /
1076 operandLitValue (right)));
1079 if ((TYPE_UDWORD) operandLitValue (right) == 0) {
1080 werror (E_DIVIDE_BY_ZERO);
1085 if (SPEC_USIGN(let) || SPEC_USIGN(ret))
1086 /* one of the operands is unsigned */
1087 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1088 (TYPE_UDWORD) operandLitValue (right));
1090 /* both operands are signed */
1091 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1092 (TYPE_DWORD) operandLitValue (right));
1096 /* The number of left shifts is always unsigned. Signed doesn't make
1097 sense here. Shifting by a negative number is impossible. */
1098 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1099 (TYPE_UDWORD) operandLitValue (right));
1102 /* The number of right shifts is always unsigned. Signed doesn't make
1103 sense here. Shifting by a negative number is impossible. */
1104 if (SPEC_USIGN(let))
1105 /* unsigned: logic shift right */
1106 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1107 (TYPE_UDWORD) operandLitValue (right));
1109 /* signed: arithmetic shift right */
1110 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1111 (TYPE_UDWORD) operandLitValue (right));
1115 retval = operandFromLit (operandLitValue (left) ==
1116 operandLitValue (right));
1119 retval = operandFromLit (operandLitValue (left) <
1120 operandLitValue (right));
1123 retval = operandFromLit (operandLitValue (left) <=
1124 operandLitValue (right));
1127 retval = operandFromLit (operandLitValue (left) !=
1128 operandLitValue (right));
1131 retval = operandFromLit (operandLitValue (left) >
1132 operandLitValue (right));
1135 retval = operandFromLit (operandLitValue (left) >=
1136 operandLitValue (right));
1139 retval = operandFromValue (valCastLiteral (type,
1140 (TYPE_UDWORD)operandLitValue(left) &
1141 (TYPE_UDWORD)operandLitValue(right)));
1144 retval = operandFromValue (valCastLiteral (type,
1145 (TYPE_UDWORD)operandLitValue(left) |
1146 (TYPE_UDWORD)operandLitValue(right)));
1149 retval = operandFromValue (valCastLiteral (type,
1150 (TYPE_UDWORD)operandLitValue(left) ^
1151 (TYPE_UDWORD)operandLitValue(right)));
1154 retval = operandFromLit (operandLitValue (left) &&
1155 operandLitValue (right));
1158 retval = operandFromLit (operandLitValue (left) ||
1159 operandLitValue (right));
1163 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1165 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1171 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1173 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1179 retval = operandFromLit (-1 * operandLitValue (left));
1183 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1187 retval = operandFromLit (!operandLitValue (left));
1191 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1192 " operandOperation invalid operator ");
1200 /*-----------------------------------------------------------------*/
1201 /* isOperandEqual - compares two operand & return 1 if they r = */
1202 /*-----------------------------------------------------------------*/
1204 isOperandEqual (operand * left, operand * right)
1206 /* if the pointers are equal then they are equal */
1210 /* if either of them null then false */
1211 if (!left || !right)
1214 if (left->type != right->type)
1217 if (IS_SYMOP (left) && IS_SYMOP (right))
1218 return left->key == right->key;
1220 /* if types are the same */
1224 return isSymbolEqual (left->operand.symOperand,
1225 right->operand.symOperand);
1227 return (floatFromVal (left->operand.valOperand) ==
1228 floatFromVal (right->operand.valOperand));
1230 if (compareType (left->operand.typeOperand,
1231 right->operand.typeOperand) == 1)
1238 /*-------------------------------------------------------------------*/
1239 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1240 /*-------------------------------------------------------------------*/
1242 isiCodeEqual (iCode * left, iCode * right)
1244 /* if the same pointer */
1248 /* if either of them null */
1249 if (!left || !right)
1252 /* if operand are the same */
1253 if (left->op == right->op)
1256 /* compare all the elements depending on type */
1257 if (left->op != IFX)
1259 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1261 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1267 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1269 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1271 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1280 /*-----------------------------------------------------------------*/
1281 /* newiTempFromOp - create a temp Operand with same attributes */
1282 /*-----------------------------------------------------------------*/
1284 newiTempFromOp (operand * op)
1294 nop = newiTempOperand (operandType (op), TRUE);
1295 nop->isaddr = op->isaddr;
1296 nop->isvolatile = op->isvolatile;
1297 nop->isGlobal = op->isGlobal;
1298 nop->isLiteral = op->isLiteral;
1299 nop->usesDefs = op->usesDefs;
1300 nop->isParm = op->isParm;
1304 /*-----------------------------------------------------------------*/
1305 /* operand from operand - creates an operand holder for the type */
1306 /*-----------------------------------------------------------------*/
1308 operandFromOperand (operand * op)
1314 nop = newOperand ();
1315 nop->type = op->type;
1316 nop->isaddr = op->isaddr;
1318 nop->isvolatile = op->isvolatile;
1319 nop->isGlobal = op->isGlobal;
1320 nop->isLiteral = op->isLiteral;
1321 nop->usesDefs = op->usesDefs;
1322 nop->isParm = op->isParm;
1327 nop->operand.symOperand = op->operand.symOperand;
1330 nop->operand.valOperand = op->operand.valOperand;
1333 nop->operand.typeOperand = op->operand.typeOperand;
1340 /*-----------------------------------------------------------------*/
1341 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1342 /*-----------------------------------------------------------------*/
1344 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1346 operand *nop = operandFromOperand (op);
1348 if (nop->type == SYMBOL)
1350 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1351 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1357 /*-----------------------------------------------------------------*/
1358 /* operandFromSymbol - creates an operand from a symbol */
1359 /*-----------------------------------------------------------------*/
1361 operandFromSymbol (symbol * sym)
1366 /* if the symbol's type is a literal */
1367 /* then it is an enumerator type */
1368 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1369 return operandFromValue (valFromType (sym->etype));
1372 sym->key = ++operandKey;
1374 /* if this an implicit variable, means struct/union */
1375 /* member so just return it */
1376 if (sym->implicit || IS_FUNC (sym->type))
1380 op->operand.symOperand = sym;
1382 op->isvolatile = isOperandVolatile (op, TRUE);
1383 op->isGlobal = isOperandGlobal (op);
1387 /* under the following conditions create a
1388 register equivalent for a local symbol */
1389 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1390 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1391 (!(options.model == MODEL_FLAT24)) ) &&
1392 options.stackAuto == 0)
1395 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1396 !IS_FUNC (sym->type) && /* not a function */
1397 !sym->_isparm && /* not a parameter */
1398 sym->level && /* is a local variable */
1399 !sym->addrtaken && /* whose address has not been taken */
1400 !sym->reqv && /* does not already have a reg equivalence */
1401 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1402 !IS_STATIC (sym->etype) && /* and not declared static */
1403 !sym->islbl && /* not a label */
1404 ok && /* farspace check */
1405 !IS_BITVAR (sym->etype) /* not a bit variable */
1409 /* we will use it after all optimizations
1410 and before liveRange calculation */
1411 sym->reqv = newiTempOperand (sym->type, 0);
1412 sym->reqv->key = sym->key;
1413 OP_SYMBOL (sym->reqv)->key = sym->key;
1414 OP_SYMBOL (sym->reqv)->isreqv = 1;
1415 OP_SYMBOL (sym->reqv)->islocal = 1;
1416 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1417 SPIL_LOC (sym->reqv) = sym;
1420 if (!IS_AGGREGATE (sym->type))
1424 op->operand.symOperand = sym;
1427 op->isvolatile = isOperandVolatile (op, TRUE);
1428 op->isGlobal = isOperandGlobal (op);
1429 op->isPtr = IS_PTR (operandType (op));
1430 op->isParm = sym->_isparm;
1435 /* itemp = &[_symbol] */
1437 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1438 IC_LEFT (ic)->type = SYMBOL;
1439 IC_LEFT (ic)->operand.symOperand = sym;
1440 IC_LEFT (ic)->key = sym->key;
1441 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1442 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1443 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1446 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1447 if (IS_ARRAY (sym->type))
1449 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1450 IC_RESULT (ic)->isaddr = 0;
1453 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1457 return IC_RESULT (ic);
1460 /*-----------------------------------------------------------------*/
1461 /* operandFromValue - creates an operand from value */
1462 /*-----------------------------------------------------------------*/
1464 operandFromValue (value * val)
1468 /* if this is a symbol then do the symbol thing */
1470 return operandFromSymbol (val->sym);
1472 /* this is not a symbol */
1475 op->operand.valOperand = val;
1476 op->isLiteral = isOperandLiteral (op);
1480 /*-----------------------------------------------------------------*/
1481 /* operandFromLink - operand from typeChain */
1482 /*-----------------------------------------------------------------*/
1484 operandFromLink (sym_link * type)
1488 /* operand from sym_link */
1494 op->operand.typeOperand = copyLinkChain (type);
1498 /*-----------------------------------------------------------------*/
1499 /* operandFromLit - makes an operand from a literal value */
1500 /*-----------------------------------------------------------------*/
1502 operandFromLit (double i)
1504 return operandFromValue (valueFromLit (i));
1507 /*-----------------------------------------------------------------*/
1508 /* operandFromAst - creates an operand from an ast */
1509 /*-----------------------------------------------------------------*/
1511 operandFromAst (ast * tree,int lvl)
1517 /* depending on type do */
1521 return ast2iCode (tree,lvl+1);
1525 return operandFromValue (tree->opval.val);
1529 return operandFromLink (tree->opval.lnk);
1536 /* Just to keep the compiler happy */
1537 return (operand *) 0;
1540 /*-----------------------------------------------------------------*/
1541 /* setOperandType - sets the operand's type to the given type */
1542 /*-----------------------------------------------------------------*/
1544 setOperandType (operand * op, sym_link * type)
1546 /* depending on the type of operand */
1551 op->operand.valOperand->etype =
1552 getSpec (op->operand.valOperand->type =
1553 copyLinkChain (type));
1557 if (op->operand.symOperand->isitmp)
1558 op->operand.symOperand->etype =
1559 getSpec (op->operand.symOperand->type =
1560 copyLinkChain (type));
1562 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1563 "attempt to modify type of source");
1567 op->operand.typeOperand = copyLinkChain (type);
1572 /*-----------------------------------------------------------------*/
1573 /* Get size in byte of ptr need to access an array */
1574 /*-----------------------------------------------------------------*/
1576 getArraySizePtr (operand * op)
1578 sym_link *ltype = operandType(op);
1582 int size = getSize(ltype);
1583 return(IS_GENPTR(ltype)?(size-1):size);
1588 sym_link *letype = getSpec(ltype);
1589 switch (PTR_TYPE (SPEC_OCLS (letype)))
1601 return (GPTRSIZE-1);
1610 /*-----------------------------------------------------------------*/
1611 /* perform "usual unary conversions" */
1612 /*-----------------------------------------------------------------*/
1614 usualUnaryConversions (operand * op)
1616 if (IS_INTEGRAL (operandType (op)))
1618 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1621 return geniCodeCast (INTTYPE, op, TRUE);
1627 /*-----------------------------------------------------------------*/
1628 /* perform "usual binary conversions" */
1629 /*-----------------------------------------------------------------*/
1631 usualBinaryConversions (operand ** op1, operand ** op2)
1634 sym_link *rtype = operandType (*op2);
1635 sym_link *ltype = operandType (*op1);
1637 ctype = computeType (ltype, rtype);
1639 *op1 = geniCodeCast (ctype, *op1, TRUE);
1640 *op2 = geniCodeCast (ctype, *op2, TRUE);
1645 /*-----------------------------------------------------------------*/
1646 /* geniCodeValueAtAddress - generate intermeditate code for value */
1648 /*-----------------------------------------------------------------*/
1650 geniCodeRValue (operand * op, bool force)
1653 sym_link *type = operandType (op);
1654 sym_link *etype = getSpec (type);
1656 /* if this is an array & already */
1657 /* an address then return this */
1658 if (IS_AGGREGATE (type) ||
1659 (IS_PTR (type) && !force && !op->isaddr))
1660 return operandFromOperand (op);
1662 /* if this is not an address then must be */
1663 /* rvalue already so return this one */
1667 /* if this is not a temp symbol then */
1668 if (!IS_ITEMP (op) &&
1670 !IN_FARSPACE (SPEC_OCLS (etype)))
1672 op = operandFromOperand (op);
1677 if (IS_SPEC (type) &&
1678 IS_TRUE_SYMOP (op) &&
1679 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1680 (options.model == MODEL_FLAT24) ))
1682 op = operandFromOperand (op);
1687 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1688 if (IS_PTR (type) && op->isaddr && force)
1691 type = copyLinkChain (type);
1693 IC_RESULT (ic) = newiTempOperand (type, 1);
1694 IC_RESULT (ic)->isaddr = 0;
1696 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1700 return IC_RESULT (ic);
1703 /*-----------------------------------------------------------------*/
1704 /* geniCodeCast - changes the value from one type to another */
1705 /*-----------------------------------------------------------------*/
1707 geniCodeCast (sym_link * type, operand * op, bool implicit)
1711 sym_link *opetype = getSpec (optype = operandType (op));
1715 /* one of them has size zero then error */
1716 if (IS_VOID (optype))
1718 werror (E_CAST_ZERO);
1722 /* if the operand is already the desired type then do nothing */
1723 if (compareType (type, optype) == 1)
1726 /* if this is a literal then just change the type & return */
1727 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1728 return operandFromValue (valCastLiteral (type,
1729 operandLitValue (op)));
1731 /* if casting to/from pointers, do some checking */
1732 if (IS_PTR(type)) { // to a pointer
1733 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1734 if (IS_INTEGRAL(optype)) {
1735 // maybe this is NULL, than it's ok.
1736 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1737 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1738 // no way to set the storage
1739 if (IS_LITERAL(optype)) {
1740 werror(E_LITERAL_GENERIC);
1743 werror(E_NONPTR2_GENPTR);
1746 } else if (implicit) {
1747 werror(W_INTEGRAL2PTR_NOCAST);
1752 // shouldn't do that with float, array or structure unless to void
1753 if (!IS_VOID(getSpec(type)) &&
1754 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1755 werror(E_INCOMPAT_TYPES);
1759 } else { // from a pointer to a pointer
1760 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1761 // if not a pointer to a function
1762 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1763 if (implicit) { // if not to generic, they have to match
1764 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1765 werror(E_INCOMPAT_PTYPES);
1772 } else { // to a non pointer
1773 if (IS_PTR(optype)) { // from a pointer
1774 if (implicit) { // sneaky
1775 if (IS_INTEGRAL(type)) {
1776 werror(W_PTR2INTEGRAL_NOCAST);
1778 } else { // shouldn't do that with float, array or structure
1779 werror(E_INCOMPAT_TYPES);
1786 printFromToType (optype, type);
1789 /* if they are the same size create an assignment */
1790 if (getSize (type) == getSize (optype) &&
1791 !IS_BITFIELD (type) &&
1793 !IS_FLOAT (optype) &&
1794 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1795 (!IS_SPEC (type) && !IS_SPEC (optype))))
1798 ic = newiCode ('=', NULL, op);
1799 IC_RESULT (ic) = newiTempOperand (type, 0);
1800 SPIL_LOC (IC_RESULT (ic)) =
1801 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1802 IC_RESULT (ic)->isaddr = 0;
1806 ic = newiCode (CAST, operandFromLink (type),
1807 geniCodeRValue (op, FALSE));
1809 IC_RESULT (ic) = newiTempOperand (type, 0);
1812 /* preserve the storage class & output class */
1813 /* of the original variable */
1814 restype = getSpec (operandType (IC_RESULT (ic)));
1815 if (!IS_LITERAL(opetype))
1816 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1817 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1820 return IC_RESULT (ic);
1823 /*-----------------------------------------------------------------*/
1824 /* geniCodeLabel - will create a Label */
1825 /*-----------------------------------------------------------------*/
1827 geniCodeLabel (symbol * label)
1831 ic = newiCodeLabelGoto (LABEL, label);
1835 /*-----------------------------------------------------------------*/
1836 /* geniCodeGoto - will create a Goto */
1837 /*-----------------------------------------------------------------*/
1839 geniCodeGoto (symbol * label)
1843 ic = newiCodeLabelGoto (GOTO, label);
1847 /*-----------------------------------------------------------------*/
1848 /* geniCodeMultiply - gen intermediate code for multiplication */
1849 /*-----------------------------------------------------------------*/
1851 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1858 /* if they are both literal then we know the result */
1859 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1860 return operandFromValue (valMult (left->operand.valOperand,
1861 right->operand.valOperand));
1863 if (IS_LITERAL(retype)) {
1864 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1867 resType = usualBinaryConversions (&left, &right);
1869 rtype = operandType (right);
1870 retype = getSpec (rtype);
1871 ltype = operandType (left);
1872 letype = getSpec (ltype);
1876 SPEC_NOUN(getSpec(resType))=V_INT;
1879 /* if the right is a literal & power of 2 */
1880 /* then make it a left shift */
1881 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1882 efficient in most cases than 2 bytes result = 2 bytes << literal
1883 if port has 1 byte muldiv */
1884 if (p2 && !IS_FLOAT (letype) &&
1885 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1886 (port->support.muldiv == 1)))
1888 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1890 /* LEFT_OP need same size for left and result, */
1891 left = geniCodeCast (resType, left, TRUE);
1892 ltype = operandType (left);
1894 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1898 ic = newiCode ('*', left, right); /* normal multiplication */
1899 /* if the size left or right > 1 then support routine */
1900 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1904 IC_RESULT (ic) = newiTempOperand (resType, 1);
1907 return IC_RESULT (ic);
1910 /*-----------------------------------------------------------------*/
1911 /* geniCodeDivision - gen intermediate code for division */
1912 /*-----------------------------------------------------------------*/
1914 geniCodeDivision (operand * left, operand * right)
1919 sym_link *rtype = operandType (right);
1920 sym_link *retype = getSpec (rtype);
1921 sym_link *ltype = operandType (left);
1922 sym_link *letype = getSpec (ltype);
1924 resType = usualBinaryConversions (&left, &right);
1926 /* if the right is a literal & power of 2
1927 and left is unsigned then make it a
1929 if (IS_LITERAL (retype) &&
1930 !IS_FLOAT (letype) &&
1931 SPEC_USIGN(letype) &&
1932 (p2 = powof2 ((unsigned long)
1933 floatFromVal (right->operand.valOperand)))) {
1934 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1938 ic = newiCode ('/', left, right); /* normal division */
1939 /* if the size left or right > 1 then support routine */
1940 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1943 IC_RESULT (ic) = newiTempOperand (resType, 0);
1946 return IC_RESULT (ic);
1948 /*-----------------------------------------------------------------*/
1949 /* geniCodeModulus - gen intermediate code for modulus */
1950 /*-----------------------------------------------------------------*/
1952 geniCodeModulus (operand * left, operand * right)
1958 /* if they are both literal then we know the result */
1959 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1960 return operandFromValue (valMod (left->operand.valOperand,
1961 right->operand.valOperand));
1963 resType = usualBinaryConversions (&left, &right);
1965 /* now they are the same size */
1966 ic = newiCode ('%', left, right);
1968 /* if the size left or right > 1 then support routine */
1969 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1971 IC_RESULT (ic) = newiTempOperand (resType, 0);
1974 return IC_RESULT (ic);
1977 /*-----------------------------------------------------------------*/
1978 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1979 /*-----------------------------------------------------------------*/
1981 geniCodePtrPtrSubtract (operand * left, operand * right)
1987 /* if they are both literals then */
1988 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1990 result = operandFromValue (valMinus (left->operand.valOperand,
1991 right->operand.valOperand));
1995 ic = newiCode ('-', left, right);
1997 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2001 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2005 // should we really do this? is this ANSI?
2006 return geniCodeDivision (result,
2007 operandFromLit (getSize (ltype->next)));
2010 /*-----------------------------------------------------------------*/
2011 /* geniCodeSubtract - generates code for subtraction */
2012 /*-----------------------------------------------------------------*/
2014 geniCodeSubtract (operand * left, operand * right)
2021 /* if they both pointers then */
2022 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2023 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2024 return geniCodePtrPtrSubtract (left, right);
2026 /* if they are both literal then we know the result */
2027 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2028 && left->isLiteral && right->isLiteral)
2029 return operandFromValue (valMinus (left->operand.valOperand,
2030 right->operand.valOperand));
2032 /* if left is an array or pointer */
2033 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2035 isarray = left->isaddr;
2036 right = geniCodeMultiply (right,
2037 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2038 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2041 { /* make them the same size */
2042 resType = usualBinaryConversions (&left, &right);
2045 ic = newiCode ('-', left, right);
2047 IC_RESULT (ic) = newiTempOperand (resType, 1);
2048 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2050 /* if left or right is a float */
2051 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2055 return IC_RESULT (ic);
2058 /*-----------------------------------------------------------------*/
2059 /* geniCodeAdd - generates iCode for addition */
2060 /*-----------------------------------------------------------------*/
2062 geniCodeAdd (operand * left, operand * right, int lvl)
2070 /* if the right side is LITERAL zero */
2071 /* return the left side */
2072 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2075 /* if left is literal zero return right */
2076 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2079 /* if left is a pointer then size */
2080 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2082 isarray = left->isaddr;
2083 // there is no need to multiply with 1
2084 if (getSize(ltype->next)!=1) {
2085 size = operandFromLit (getSize (ltype->next));
2086 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2088 resType = copyLinkChain (ltype);
2091 { // make them the same size
2092 resType = usualBinaryConversions (&left, &right);
2095 /* if they are both literals then we know */
2096 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2097 && left->isLiteral && right->isLiteral)
2098 return operandFromValue (valPlus (valFromType (letype),
2099 valFromType (retype)));
2101 ic = newiCode ('+', left, right);
2103 IC_RESULT (ic) = newiTempOperand (resType, 1);
2104 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2106 /* if left or right is a float then support
2108 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2113 return IC_RESULT (ic);
2117 /*-----------------------------------------------------------------*/
2118 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2119 /*-----------------------------------------------------------------*/
2121 aggrToPtr (sym_link * type, bool force)
2127 if (IS_PTR (type) && !force)
2130 etype = getSpec (type);
2131 ptype = newLink (DECLARATOR);
2135 /* if the output class is code */
2136 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2137 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2139 /* if the variable was declared a constant */
2140 /* then the pointer points to a constant */
2141 if (IS_CONSTANT (etype))
2142 DCL_PTR_CONST (ptype) = 1;
2144 /* the variable was volatile then pointer to volatile */
2145 if (IS_VOLATILE (etype))
2146 DCL_PTR_VOLATILE (ptype) = 1;
2151 /*-----------------------------------------------------------------*/
2152 /* geniCodeArray2Ptr - array to pointer */
2153 /*-----------------------------------------------------------------*/
2155 geniCodeArray2Ptr (operand * op)
2157 sym_link *optype = operandType (op);
2158 sym_link *opetype = getSpec (optype);
2160 /* set the pointer depending on the storage class */
2161 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2162 DCL_PTR_CONST (optype) = port->mem.code_ro;
2164 /* if the variable was declared a constant */
2165 /* then the pointer points to a constant */
2166 if (IS_CONSTANT (opetype))
2167 DCL_PTR_CONST (optype) = 1;
2169 /* the variable was volatile then pointer to volatile */
2170 if (IS_VOLATILE (opetype))
2171 DCL_PTR_VOLATILE (optype) = 1;
2178 /*-----------------------------------------------------------------*/
2179 /* geniCodeArray - array access */
2180 /*-----------------------------------------------------------------*/
2182 geniCodeArray (operand * left, operand * right,int lvl)
2185 sym_link *ltype = operandType (left);
2189 if (IS_PTR (ltype->next) && left->isaddr)
2191 left = geniCodeRValue (left, FALSE);
2193 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2196 right = geniCodeMultiply (right,
2197 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2199 /* we can check for limits here */
2200 if (isOperandLiteral (right) &&
2203 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2205 werror (E_ARRAY_BOUND);
2206 right = operandFromLit (0);
2209 ic = newiCode ('+', left, right);
2211 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2212 !IS_AGGREGATE (ltype->next) &&
2213 !IS_PTR (ltype->next))
2214 ? ltype : ltype->next), 0);
2216 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2218 return IC_RESULT (ic);
2221 /*-----------------------------------------------------------------*/
2222 /* geniCodeStruct - generates intermediate code for structres */
2223 /*-----------------------------------------------------------------*/
2225 geniCodeStruct (operand * left, operand * right, bool islval)
2228 sym_link *type = operandType (left);
2229 sym_link *etype = getSpec (type);
2231 symbol *element = getStructElement (SPEC_STRUCT (etype),
2232 right->operand.symOperand);
2234 wassert(IS_SYMOP(right));
2236 /* add the offset */
2237 ic = newiCode ('+', left, operandFromLit (element->offset));
2239 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2241 /* preserve the storage & output class of the struct */
2242 /* as well as the volatile attribute */
2243 retype = getSpec (operandType (IC_RESULT (ic)));
2244 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2245 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2246 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2248 if (IS_PTR (element->type))
2249 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2251 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2255 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2258 /*-----------------------------------------------------------------*/
2259 /* geniCodePostInc - generate int code for Post increment */
2260 /*-----------------------------------------------------------------*/
2262 geniCodePostInc (operand * op)
2266 sym_link *optype = operandType (op);
2268 operand *rv = (IS_ITEMP (op) ?
2269 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2271 sym_link *rvtype = operandType (rv);
2274 /* if this is not an address we have trouble */
2277 werror (E_LVALUE_REQUIRED, "++");
2281 rOp = newiTempOperand (rvtype, 0);
2282 OP_SYMBOL(rOp)->noSpilLoc = 1;
2285 OP_SYMBOL(rv)->noSpilLoc = 1;
2287 geniCodeAssign (rOp, rv, 0);
2289 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2290 if (IS_FLOAT (rvtype))
2291 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2293 ic = newiCode ('+', rv, operandFromLit (size));
2295 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2298 geniCodeAssign (op, result, 0);
2304 /*-----------------------------------------------------------------*/
2305 /* geniCodePreInc - generate code for preIncrement */
2306 /*-----------------------------------------------------------------*/
2308 geniCodePreInc (operand * op)
2311 sym_link *optype = operandType (op);
2312 operand *rop = (IS_ITEMP (op) ?
2313 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2315 sym_link *roptype = operandType (rop);
2321 werror (E_LVALUE_REQUIRED, "++");
2326 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2327 if (IS_FLOAT (roptype))
2328 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2330 ic = newiCode ('+', rop, operandFromLit (size));
2331 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2335 return geniCodeAssign (op, result, 0);
2338 /*-----------------------------------------------------------------*/
2339 /* geniCodePostDec - generates code for Post decrement */
2340 /*-----------------------------------------------------------------*/
2342 geniCodePostDec (operand * op)
2346 sym_link *optype = operandType (op);
2348 operand *rv = (IS_ITEMP (op) ?
2349 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2351 sym_link *rvtype = operandType (rv);
2354 /* if this is not an address we have trouble */
2357 werror (E_LVALUE_REQUIRED, "--");
2361 rOp = newiTempOperand (rvtype, 0);
2362 OP_SYMBOL(rOp)->noSpilLoc = 1;
2365 OP_SYMBOL(rv)->noSpilLoc = 1;
2367 geniCodeAssign (rOp, rv, 0);
2369 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2370 if (IS_FLOAT (rvtype))
2371 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2373 ic = newiCode ('-', rv, operandFromLit (size));
2375 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2378 geniCodeAssign (op, result, 0);
2384 /*-----------------------------------------------------------------*/
2385 /* geniCodePreDec - generate code for pre decrement */
2386 /*-----------------------------------------------------------------*/
2388 geniCodePreDec (operand * op)
2391 sym_link *optype = operandType (op);
2392 operand *rop = (IS_ITEMP (op) ?
2393 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2395 sym_link *roptype = operandType (rop);
2401 werror (E_LVALUE_REQUIRED, "--");
2406 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2407 if (IS_FLOAT (roptype))
2408 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2410 ic = newiCode ('-', rop, operandFromLit (size));
2411 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2415 return geniCodeAssign (op, result, 0);
2419 /*-----------------------------------------------------------------*/
2420 /* geniCodeBitwise - gen int code for bitWise operators */
2421 /*-----------------------------------------------------------------*/
2423 geniCodeBitwise (operand * left, operand * right,
2424 int oper, sym_link * resType)
2428 left = geniCodeCast (resType, left, TRUE);
2429 right = geniCodeCast (resType, right, TRUE);
2431 ic = newiCode (oper, left, right);
2432 IC_RESULT (ic) = newiTempOperand (resType, 0);
2435 return IC_RESULT (ic);
2438 /*-----------------------------------------------------------------*/
2439 /* geniCodeAddressOf - gens icode for '&' address of operator */
2440 /*-----------------------------------------------------------------*/
2442 geniCodeAddressOf (operand * op)
2446 sym_link *optype = operandType (op);
2447 sym_link *opetype = getSpec (optype);
2449 /* lvalue check already done in decorateType */
2450 /* this must be a lvalue */
2451 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2452 /* werror (E_LVALUE_REQUIRED,"&"); */
2456 p = newLink (DECLARATOR);
2458 /* set the pointer depending on the storage class */
2459 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2460 DCL_PTR_CONST (p) = port->mem.code_ro;
2462 /* make sure we preserve the const & volatile */
2463 if (IS_CONSTANT (opetype))
2464 DCL_PTR_CONST (p) = 1;
2466 if (IS_VOLATILE (opetype))
2467 DCL_PTR_VOLATILE (p) = 1;
2469 p->next = copyLinkChain (optype);
2471 /* if already a temp */
2474 setOperandType (op, p);
2479 /* other wise make this of the type coming in */
2480 ic = newiCode (ADDRESS_OF, op, NULL);
2481 IC_RESULT (ic) = newiTempOperand (p, 1);
2482 IC_RESULT (ic)->isaddr = 0;
2484 return IC_RESULT (ic);
2486 /*-----------------------------------------------------------------*/
2487 /* setOClass - sets the output class depending on the pointer type */
2488 /*-----------------------------------------------------------------*/
2490 setOClass (sym_link * ptr, sym_link * spec)
2492 switch (DCL_TYPE (ptr))
2495 SPEC_OCLS (spec) = data;
2499 SPEC_OCLS (spec) = generic;
2503 SPEC_OCLS (spec) = xdata;
2507 SPEC_OCLS (spec) = code;
2511 SPEC_OCLS (spec) = idata;
2515 SPEC_OCLS (spec) = xstack;
2519 SPEC_OCLS (spec) = eeprom;
2528 /*-----------------------------------------------------------------*/
2529 /* geniCodeDerefPtr - dereference pointer with '*' */
2530 /*-----------------------------------------------------------------*/
2532 geniCodeDerefPtr (operand * op,int lvl)
2534 sym_link *rtype, *retype;
2535 sym_link *optype = operandType (op);
2537 // if this is an array then array access
2538 if (IS_ARRAY (optype)) {
2539 // don't worry, this will be optimized out later
2540 return geniCodeArray (op, operandFromLit (0), lvl);
2543 // just in case someone screws up
2544 wassert (IS_PTR (optype));
2546 if (IS_TRUE_SYMOP (op))
2549 op = geniCodeRValue (op, TRUE);
2552 /* now get rid of the pointer part */
2553 if (isLvaluereq(lvl) && IS_ITEMP (op))
2555 retype = getSpec (rtype = copyLinkChain (optype));
2559 retype = getSpec (rtype = copyLinkChain (optype->next));
2562 /* outputclass needs 2b updated */
2563 setOClass (optype, retype);
2565 op->isGptr = IS_GENPTR (optype);
2567 /* if the pointer was declared as a constant */
2568 /* then we cannot allow assignment to the derefed */
2569 if (IS_PTR_CONST (optype))
2570 SPEC_CONST (retype) = 1;
2572 op->isaddr = (IS_PTR (rtype) ||
2573 IS_STRUCT (rtype) ||
2578 if (!isLvaluereq(lvl))
2579 op = geniCodeRValue (op, TRUE);
2581 setOperandType (op, rtype);
2586 /*-----------------------------------------------------------------*/
2587 /* geniCodeUnaryMinus - does a unary minus of the operand */
2588 /*-----------------------------------------------------------------*/
2590 geniCodeUnaryMinus (operand * op)
2593 sym_link *optype = operandType (op);
2595 if (IS_LITERAL (optype))
2596 return operandFromLit (-floatFromVal (op->operand.valOperand));
2598 ic = newiCode (UNARYMINUS, op, NULL);
2599 IC_RESULT (ic) = newiTempOperand (optype, 0);
2601 return IC_RESULT (ic);
2604 /*-----------------------------------------------------------------*/
2605 /* geniCodeLeftShift - gen i code for left shift */
2606 /*-----------------------------------------------------------------*/
2608 geniCodeLeftShift (operand * left, operand * right)
2612 ic = newiCode (LEFT_OP, left, right);
2613 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2615 return IC_RESULT (ic);
2618 /*-----------------------------------------------------------------*/
2619 /* geniCodeRightShift - gen i code for right shift */
2620 /*-----------------------------------------------------------------*/
2622 geniCodeRightShift (operand * left, operand * right)
2626 ic = newiCode (RIGHT_OP, left, right);
2627 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2629 return IC_RESULT (ic);
2632 /*-----------------------------------------------------------------*/
2633 /* geniCodeLogic- logic code */
2634 /*-----------------------------------------------------------------*/
2636 geniCodeLogic (operand * left, operand * right, int op)
2640 sym_link *rtype = operandType (right);
2641 sym_link *ltype = operandType (left);
2643 /* left is integral type and right is literal then
2644 check if the literal value is within bounds */
2645 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2647 checkConstantRange(ltype,
2648 OP_VALUE(right), "compare operation", 1);
2651 ctype = usualBinaryConversions (&left, &right);
2653 ic = newiCode (op, left, right);
2654 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2656 /* if comparing float
2657 and not a '==' || '!=' || '&&' || '||' (these
2659 if (IS_FLOAT(ctype) &&
2667 return IC_RESULT (ic);
2670 /*-----------------------------------------------------------------*/
2671 /* geniCodeUnary - for a a generic unary operation */
2672 /*-----------------------------------------------------------------*/
2674 geniCodeUnary (operand * op, int oper)
2676 iCode *ic = newiCode (oper, op, NULL);
2678 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2680 return IC_RESULT (ic);
2683 /*-----------------------------------------------------------------*/
2684 /* geniCodeConditional - geniCode for '?' ':' operation */
2685 /*-----------------------------------------------------------------*/
2687 geniCodeConditional (ast * tree,int lvl)
2690 symbol *falseLabel = newiTempLabel (NULL);
2691 symbol *exitLabel = newiTempLabel (NULL);
2692 operand *cond = ast2iCode (tree->left,lvl+1);
2693 operand *true, *false, *result;
2695 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2699 true = ast2iCode (tree->right->left,lvl+1);
2701 /* move the value to a new Operand */
2702 result = newiTempOperand (tree->right->ftype, 0);
2703 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2705 /* generate an unconditional goto */
2706 geniCodeGoto (exitLabel);
2708 /* now for the right side */
2709 geniCodeLabel (falseLabel);
2711 false = ast2iCode (tree->right->right,lvl+1);
2712 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2714 /* create the exit label */
2715 geniCodeLabel (exitLabel);
2720 /*-----------------------------------------------------------------*/
2721 /* geniCodeAssign - generate code for assignment */
2722 /*-----------------------------------------------------------------*/
2724 geniCodeAssign (operand * left, operand * right, int nosupdate)
2727 sym_link *ltype = operandType (left);
2728 sym_link *rtype = operandType (right);
2730 if (!left->isaddr && !IS_ITEMP (left))
2732 werror (E_LVALUE_REQUIRED, "assignment");
2736 /* left is integral type and right is literal then
2737 check if the literal value is within bounds */
2738 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2740 checkConstantRange(ltype,
2741 OP_VALUE(right), "= operation", 0);
2744 /* if the left & right type don't exactly match */
2745 /* if pointer set then make sure the check is
2746 done with the type & not the pointer */
2747 /* then cast rights type to left */
2749 /* first check the type for pointer assignement */
2750 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2751 compareType (ltype, rtype) <= 0)
2753 if (compareType (ltype->next, rtype) < 0)
2754 right = geniCodeCast (ltype->next, right, TRUE);
2756 else if (compareType (ltype, rtype) < 0)
2757 right = geniCodeCast (ltype, right, TRUE);
2759 /* if left is a true symbol & ! volatile
2760 create an assignment to temporary for
2761 the right & then assign this temporary
2762 to the symbol this is SSA . isn't it simple
2763 and folks have published mountains of paper on it */
2764 if (IS_TRUE_SYMOP (left) &&
2765 !isOperandVolatile (left, FALSE) &&
2766 isOperandGlobal (left))
2770 if (IS_TRUE_SYMOP (right))
2771 sym = OP_SYMBOL (right);
2772 ic = newiCode ('=', NULL, right);
2773 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2774 SPIL_LOC (right) = sym;
2778 ic = newiCode ('=', NULL, right);
2779 IC_RESULT (ic) = left;
2782 /* if left isgptr flag is set then support
2783 routine will be required */
2787 ic->nosupdate = nosupdate;
2791 /*-----------------------------------------------------------------*/
2792 /* geniCodeSEParms - generate code for side effecting fcalls */
2793 /*-----------------------------------------------------------------*/
2795 geniCodeSEParms (ast * parms,int lvl)
2800 if (parms->type == EX_OP && parms->opval.op == PARAM)
2802 geniCodeSEParms (parms->left,lvl);
2803 geniCodeSEParms (parms->right,lvl);
2807 /* hack don't like this but too lazy to think of
2809 if (IS_ADDRESS_OF_OP (parms))
2810 parms->left->lvalue = 1;
2812 if (IS_CAST_OP (parms) &&
2813 IS_PTR (parms->ftype) &&
2814 IS_ADDRESS_OF_OP (parms->right))
2815 parms->right->left->lvalue = 1;
2817 parms->opval.oprnd =
2818 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2820 parms->type = EX_OPERAND;
2821 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2822 SPEC_ARGREG(parms->ftype);
2825 /*-----------------------------------------------------------------*/
2826 /* geniCodeParms - generates parameters */
2827 /*-----------------------------------------------------------------*/
2829 geniCodeParms (ast * parms, value *argVals, int *stack,
2830 sym_link * fetype, symbol * func,int lvl)
2838 if (argVals==NULL) {
2840 argVals=FUNC_ARGS(func->type);
2843 /* if this is a param node then do the left & right */
2844 if (parms->type == EX_OP && parms->opval.op == PARAM)
2846 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2847 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2851 /* get the parameter value */
2852 if (parms->type == EX_OPERAND)
2853 pval = parms->opval.oprnd;
2856 /* maybe this else should go away ?? */
2857 /* hack don't like this but too lazy to think of
2859 if (IS_ADDRESS_OF_OP (parms))
2860 parms->left->lvalue = 1;
2862 if (IS_CAST_OP (parms) &&
2863 IS_PTR (parms->ftype) &&
2864 IS_ADDRESS_OF_OP (parms->right))
2865 parms->right->left->lvalue = 1;
2867 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2870 /* if register parm then make it a send */
2871 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2872 IFFUNC_ISBUILTIN(func->type))
2874 ic = newiCode (SEND, pval, NULL);
2875 ic->argreg = SPEC_ARGREG(parms->etype);
2876 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2881 /* now decide whether to push or assign */
2882 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2886 operand *top = operandFromSymbol (argVals->sym);
2887 /* clear useDef and other bitVectors */
2888 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
2889 geniCodeAssign (top, pval, 1);
2893 sym_link *p = operandType (pval);
2895 ic = newiCode (IPUSH, pval, NULL);
2897 /* update the stack adjustment */
2898 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2903 argVals=argVals->next;
2907 /*-----------------------------------------------------------------*/
2908 /* geniCodeCall - generates temp code for calling */
2909 /*-----------------------------------------------------------------*/
2911 geniCodeCall (operand * left, ast * parms,int lvl)
2915 sym_link *type, *etype;
2918 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2919 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2920 werror (E_FUNCTION_EXPECTED);
2924 /* take care of parameters with side-effecting
2925 function calls in them, this is required to take care
2926 of overlaying function parameters */
2927 geniCodeSEParms (parms,lvl);
2929 /* first the parameters */
2930 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2932 /* now call : if symbol then pcall */
2933 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
2934 ic = newiCode (PCALL, left, NULL);
2936 ic = newiCode (CALL, left, NULL);
2939 type = copyLinkChain (operandType (left)->next);
2940 etype = getSpec (type);
2941 SPEC_EXTR (etype) = 0;
2942 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2946 /* stack adjustment after call */
2947 ic->parmBytes = stack;
2952 /*-----------------------------------------------------------------*/
2953 /* geniCodeReceive - generate intermediate code for "receive" */
2954 /*-----------------------------------------------------------------*/
2956 geniCodeReceive (value * args)
2958 /* for all arguments that are passed in registers */
2962 if (IS_REGPARM (args->etype))
2964 operand *opr = operandFromValue (args);
2966 symbol *sym = OP_SYMBOL (opr);
2969 /* we will use it after all optimizations
2970 and before liveRange calculation */
2971 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2974 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2975 options.stackAuto == 0 &&
2976 (!(options.model == MODEL_FLAT24)) )
2981 opl = newiTempOperand (args->type, 0);
2983 sym->reqv->key = sym->key;
2984 OP_SYMBOL (sym->reqv)->key = sym->key;
2985 OP_SYMBOL (sym->reqv)->isreqv = 1;
2986 OP_SYMBOL (sym->reqv)->islocal = 0;
2987 SPIL_LOC (sym->reqv) = sym;
2991 ic = newiCode (RECEIVE, NULL, NULL);
2992 ic->argreg = SPEC_ARGREG(args->etype);
2994 currFunc->recvSize = getSize (sym->type);
2997 IC_RESULT (ic) = opr;
3005 /*-----------------------------------------------------------------*/
3006 /* geniCodeFunctionBody - create the function body */
3007 /*-----------------------------------------------------------------*/
3009 geniCodeFunctionBody (ast * tree,int lvl)
3016 /* reset the auto generation */
3022 func = ast2iCode (tree->left,lvl+1);
3023 fetype = getSpec (operandType (func));
3025 savelineno = lineno;
3026 lineno = OP_SYMBOL (func)->lineDef;
3027 /* create an entry label */
3028 geniCodeLabel (entryLabel);
3029 lineno = savelineno;
3031 /* create a proc icode */
3032 ic = newiCode (FUNCTION, func, NULL);
3033 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3037 /* for all parameters that are passed
3038 on registers add a "receive" */
3039 geniCodeReceive (tree->values.args);
3041 /* generate code for the body */
3042 ast2iCode (tree->right,lvl+1);
3044 /* create a label for return */
3045 geniCodeLabel (returnLabel);
3047 /* now generate the end proc */
3048 ic = newiCode (ENDFUNCTION, func, NULL);
3053 /*-----------------------------------------------------------------*/
3054 /* geniCodeReturn - gen icode for 'return' statement */
3055 /*-----------------------------------------------------------------*/
3057 geniCodeReturn (operand * op)
3061 /* if the operand is present force an rvalue */
3063 op = geniCodeRValue (op, FALSE);
3065 ic = newiCode (RETURN, op, NULL);
3069 /*-----------------------------------------------------------------*/
3070 /* geniCodeIfx - generates code for extended if statement */
3071 /*-----------------------------------------------------------------*/
3073 geniCodeIfx (ast * tree,int lvl)
3076 operand *condition = ast2iCode (tree->left,lvl+1);
3079 /* if condition is null then exit */
3083 condition = geniCodeRValue (condition, FALSE);
3085 cetype = getSpec (operandType (condition));
3086 /* if the condition is a literal */
3087 if (IS_LITERAL (cetype))
3089 if (floatFromVal (condition->operand.valOperand))
3091 if (tree->trueLabel)
3092 geniCodeGoto (tree->trueLabel);
3098 if (tree->falseLabel)
3099 geniCodeGoto (tree->falseLabel);
3106 if (tree->trueLabel)
3108 ic = newiCodeCondition (condition,
3113 if (tree->falseLabel)
3114 geniCodeGoto (tree->falseLabel);
3118 ic = newiCodeCondition (condition,
3125 ast2iCode (tree->right,lvl+1);
3128 /*-----------------------------------------------------------------*/
3129 /* geniCodeJumpTable - tries to create a jump table for switch */
3130 /*-----------------------------------------------------------------*/
3132 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3134 int min = 0, max = 0, t, cnt = 0;
3141 if (!tree || !caseVals)
3144 /* the criteria for creating a jump table is */
3145 /* all integer numbers between the maximum & minimum must */
3146 /* be present , the maximum value should not exceed 255 */
3147 min = max = (int) floatFromVal (vch = caseVals);
3148 SNPRINTF (buffer, sizeof(buffer),
3150 tree->values.switchVals.swNum,
3152 addSet (&labels, newiTempLabel (buffer));
3154 /* if there is only one case value then no need */
3155 if (!(vch = vch->next))
3160 if (((t = (int) floatFromVal (vch)) - max) != 1)
3162 SNPRINTF (buffer, sizeof(buffer),
3164 tree->values.switchVals.swNum,
3166 addSet (&labels, newiTempLabel (buffer));
3172 /* if the number of case statements <= 2 then */
3173 /* it is not economical to create the jump table */
3174 /* since two compares are needed for boundary conditions */
3175 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3178 if (tree->values.switchVals.swDefault)
3180 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3184 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3188 falseLabel = newiTempLabel (buffer);
3190 /* so we can create a jumptable */
3191 /* first we rule out the boundary conditions */
3192 /* if only optimization says so */
3193 if (!optimize.noJTabBoundary)
3195 sym_link *cetype = getSpec (operandType (cond));
3196 /* no need to check the lower bound if
3197 the condition is unsigned & minimum value is zero */
3198 if (!(min == 0 && SPEC_USIGN (cetype)))
3200 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3201 ic = newiCodeCondition (boundary, falseLabel, NULL);
3205 /* now for upper bounds */
3206 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3207 ic = newiCodeCondition (boundary, falseLabel, NULL);
3211 /* if the min is not zero then we no make it zero */
3214 cond = geniCodeSubtract (cond, operandFromLit (min));
3215 setOperandType (cond, UCHARTYPE);
3218 /* now create the jumptable */
3219 ic = newiCode (JUMPTABLE, NULL, NULL);
3220 IC_JTCOND (ic) = cond;
3221 IC_JTLABELS (ic) = labels;
3226 /*-----------------------------------------------------------------*/
3227 /* geniCodeSwitch - changes a switch to a if statement */
3228 /*-----------------------------------------------------------------*/
3230 geniCodeSwitch (ast * tree,int lvl)
3233 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3234 value *caseVals = tree->values.switchVals.swVals;
3235 symbol *trueLabel, *falseLabel;
3237 /* if we can make this a jump table */
3238 if (geniCodeJumpTable (cond, caseVals, tree))
3239 goto jumpTable; /* no need for the comparison */
3241 /* for the cases defined do */
3245 operand *compare = geniCodeLogic (cond,
3246 operandFromValue (caseVals),
3249 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3250 tree->values.switchVals.swNum,
3251 (int) floatFromVal (caseVals));
3252 trueLabel = newiTempLabel (buffer);
3254 ic = newiCodeCondition (compare, trueLabel, NULL);
3256 caseVals = caseVals->next;
3261 /* if default is present then goto break else break */
3262 if (tree->values.switchVals.swDefault)
3264 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3268 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3271 falseLabel = newiTempLabel (buffer);
3272 geniCodeGoto (falseLabel);
3275 ast2iCode (tree->right,lvl+1);
3278 /*-----------------------------------------------------------------*/
3279 /* geniCodeInline - intermediate code for inline assembler */
3280 /*-----------------------------------------------------------------*/
3282 geniCodeInline (ast * tree)
3286 ic = newiCode (INLINEASM, NULL, NULL);
3287 IC_INLINE (ic) = tree->values.inlineasm;
3291 /*-----------------------------------------------------------------*/
3292 /* geniCodeArrayInit - intermediate code for array initializer */
3293 /*-----------------------------------------------------------------*/
3295 geniCodeArrayInit (ast * tree, operand *array)
3299 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3300 ic = newiCode (ARRAYINIT, array, NULL);
3301 IC_ARRAYILIST (ic) = tree->values.constlist;
3303 operand *left=newOperand(), *right=newOperand();
3304 left->type=right->type=SYMBOL;
3305 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3306 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3307 ic = newiCode (ARRAYINIT, left, right);
3312 /*-----------------------------------------------------------------*/
3313 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3314 /* particular case. Ie : assigning or dereferencing array or ptr */
3315 /*-----------------------------------------------------------------*/
3316 set * lvaluereqSet = NULL;
3317 typedef struct lvalItem
3324 /*-----------------------------------------------------------------*/
3325 /* addLvaluereq - add a flag for lvalreq for current ast level */
3326 /*-----------------------------------------------------------------*/
3327 void addLvaluereq(int lvl)
3329 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3332 addSetHead(&lvaluereqSet,lpItem);
3335 /*-----------------------------------------------------------------*/
3336 /* delLvaluereq - del a flag for lvalreq for current ast level */
3337 /*-----------------------------------------------------------------*/
3341 lpItem = getSet(&lvaluereqSet);
3342 if(lpItem) Safe_free(lpItem);
3344 /*-----------------------------------------------------------------*/
3345 /* clearLvaluereq - clear lvalreq flag */
3346 /*-----------------------------------------------------------------*/
3347 void clearLvaluereq()
3350 lpItem = peekSet(lvaluereqSet);
3351 if(lpItem) lpItem->req = 0;
3353 /*-----------------------------------------------------------------*/
3354 /* getLvaluereq - get the last lvalreq level */
3355 /*-----------------------------------------------------------------*/
3356 int getLvaluereqLvl()
3359 lpItem = peekSet(lvaluereqSet);
3360 if(lpItem) return lpItem->lvl;
3363 /*-----------------------------------------------------------------*/
3364 /* isLvaluereq - is lvalreq valid for this level ? */
3365 /*-----------------------------------------------------------------*/
3366 int isLvaluereq(int lvl)
3369 lpItem = peekSet(lvaluereqSet);
3370 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3374 /*-----------------------------------------------------------------*/
3375 /* ast2iCode - creates an icodeList from an ast */
3376 /*-----------------------------------------------------------------*/
3378 ast2iCode (ast * tree,int lvl)
3380 operand *left = NULL;
3381 operand *right = NULL;
3385 /* set the global variables for filename & line number */
3387 filename = tree->filename;
3389 lineno = tree->lineno;
3391 block = tree->block;
3393 scopeLevel = tree->level;
3395 if (tree->type == EX_VALUE)
3396 return operandFromValue (tree->opval.val);
3398 if (tree->type == EX_LINK)
3399 return operandFromLink (tree->opval.lnk);
3401 /* if we find a nullop */
3402 if (tree->type == EX_OP &&
3403 (tree->opval.op == NULLOP ||
3404 tree->opval.op == BLOCK))
3406 ast2iCode (tree->left,lvl+1);
3407 ast2iCode (tree->right,lvl+1);
3411 /* special cases for not evaluating */
3412 if (tree->opval.op != ':' &&
3413 tree->opval.op != '?' &&
3414 tree->opval.op != CALL &&
3415 tree->opval.op != IFX &&
3416 tree->opval.op != LABEL &&
3417 tree->opval.op != GOTO &&
3418 tree->opval.op != SWITCH &&
3419 tree->opval.op != FUNCTION &&
3420 tree->opval.op != INLINEASM)
3423 if (IS_ASSIGN_OP (tree->opval.op) ||
3424 IS_DEREF_OP (tree) ||
3425 (tree->opval.op == '&' && !tree->right) ||
3426 tree->opval.op == PTR_OP)
3429 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3430 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3433 left = operandFromAst (tree->left,lvl);
3435 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3436 left = geniCodeRValue (left, TRUE);
3440 left = operandFromAst (tree->left,lvl);
3442 if (tree->opval.op == INC_OP ||
3443 tree->opval.op == DEC_OP)
3446 right = operandFromAst (tree->right,lvl);
3451 right = operandFromAst (tree->right,lvl);
3455 /* now depending on the type of operand */
3456 /* this will be a biggy */
3457 switch (tree->opval.op)
3460 case '[': /* array operation */
3462 //sym_link *ltype = operandType (left);
3463 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3464 left = geniCodeRValue (left, FALSE);
3465 right = geniCodeRValue (right, TRUE);
3468 return geniCodeArray (left, right,lvl);
3470 case '.': /* structure dereference */
3471 if (IS_PTR (operandType (left)))
3472 left = geniCodeRValue (left, TRUE);
3474 left = geniCodeRValue (left, FALSE);
3476 return geniCodeStruct (left, right, tree->lvalue);
3478 case PTR_OP: /* structure pointer dereference */
3481 pType = operandType (left);
3482 left = geniCodeRValue (left, TRUE);
3484 setOClass (pType, getSpec (operandType (left)));
3487 return geniCodeStruct (left, right, tree->lvalue);
3489 case INC_OP: /* increment operator */
3491 return geniCodePostInc (left);
3493 return geniCodePreInc (right);
3495 case DEC_OP: /* decrement operator */
3497 return geniCodePostDec (left);
3499 return geniCodePreDec (right);
3501 case '&': /* bitwise and or address of operator */
3503 { /* this is a bitwise operator */
3504 left = geniCodeRValue (left, FALSE);
3505 right = geniCodeRValue (right, FALSE);
3506 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3509 return geniCodeAddressOf (left);
3511 case '|': /* bitwise or & xor */
3513 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3514 geniCodeRValue (right, FALSE),
3519 return geniCodeDivision (geniCodeRValue (left, FALSE),
3520 geniCodeRValue (right, FALSE));
3523 return geniCodeModulus (geniCodeRValue (left, FALSE),
3524 geniCodeRValue (right, FALSE));
3527 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3528 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3530 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3534 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3535 geniCodeRValue (right, FALSE));
3537 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3541 return geniCodeAdd (geniCodeRValue (left, FALSE),
3542 geniCodeRValue (right, FALSE),lvl);
3544 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3547 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3548 geniCodeRValue (right, FALSE));
3551 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3552 geniCodeRValue (right, FALSE));
3554 #if 0 // this indeed needs a second thought
3558 // let's keep this simple: get the rvalue we need
3559 op=geniCodeRValue (right, FALSE);
3560 // now cast it to whatever we want
3561 op=geniCodeCast (operandType(left), op, FALSE);
3562 // if this is going to be used as an lvalue, make it so
3568 #else // bug #604575, is it a bug ????
3569 return geniCodeCast (operandType (left),
3570 geniCodeRValue (right, FALSE), FALSE);
3577 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3581 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3582 setOperandType (op, UCHARTYPE);
3593 return geniCodeLogic (geniCodeRValue (left, FALSE),
3594 geniCodeRValue (right, FALSE),
3597 return geniCodeConditional (tree,lvl);
3600 return operandFromLit (getSize (tree->right->ftype));
3604 sym_link *rtype = operandType (right);
3605 sym_link *ltype = operandType (left);
3606 if (IS_PTR (rtype) && IS_ITEMP (right)
3607 && right->isaddr && compareType (rtype->next, ltype) == 1)
3608 right = geniCodeRValue (right, TRUE);
3610 right = geniCodeRValue (right, FALSE);
3612 geniCodeAssign (left, right, 0);
3617 geniCodeAssign (left,
3618 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3620 geniCodeRValue (right, FALSE),FALSE), 0);
3624 geniCodeAssign (left,
3625 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3627 geniCodeRValue (right, FALSE)), 0);
3630 geniCodeAssign (left,
3631 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3633 geniCodeRValue (right, FALSE)), 0);
3636 sym_link *rtype = operandType (right);
3637 sym_link *ltype = operandType (left);
3638 if (IS_PTR (rtype) && IS_ITEMP (right)
3639 && right->isaddr && compareType (rtype->next, ltype) == 1)
3640 right = geniCodeRValue (right, TRUE);
3642 right = geniCodeRValue (right, FALSE);
3645 return geniCodeAssign (left,
3646 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3652 sym_link *rtype = operandType (right);
3653 sym_link *ltype = operandType (left);
3654 if (IS_PTR (rtype) && IS_ITEMP (right)
3655 && right->isaddr && compareType (rtype->next, ltype) == 1)
3657 right = geniCodeRValue (right, TRUE);
3661 right = geniCodeRValue (right, FALSE);
3664 geniCodeAssign (left,
3665 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3671 geniCodeAssign (left,
3672 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3674 geniCodeRValue (right, FALSE)), 0);
3677 geniCodeAssign (left,
3678 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3680 geniCodeRValue (right, FALSE)), 0);
3683 geniCodeAssign (left,
3684 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3686 geniCodeRValue (right, FALSE),
3688 operandType (left)), 0);
3691 geniCodeAssign (left,
3692 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3694 geniCodeRValue (right, FALSE),
3696 operandType (left)), 0);
3699 geniCodeAssign (left,
3700 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3702 geniCodeRValue (right, FALSE),
3704 operandType (left)), 0);
3706 return geniCodeRValue (right, FALSE);
3709 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3712 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3713 return ast2iCode (tree->right,lvl+1);
3716 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3717 return ast2iCode (tree->right,lvl+1);
3720 geniCodeFunctionBody (tree,lvl);
3724 geniCodeReturn (right);
3728 geniCodeIfx (tree,lvl);
3732 geniCodeSwitch (tree,lvl);
3736 geniCodeInline (tree);
3740 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3747 /*-----------------------------------------------------------------*/
3748 /* reverseICChain - gets from the list and creates a linkedlist */
3749 /*-----------------------------------------------------------------*/
3756 while ((loop = getSet (&iCodeChain)))
3768 /*-----------------------------------------------------------------*/
3769 /* iCodeFromAst - given an ast will convert it to iCode */
3770 /*-----------------------------------------------------------------*/
3772 iCodeFromAst (ast * tree)
3774 returnLabel = newiTempLabel ("_return");
3775 entryLabel = newiTempLabel ("_entry");
3777 return reverseiCChain ();
3780 static const char *opTypeToStr(OPTYPE op)
3784 case SYMBOL: return "symbol";
3785 case VALUE: return "value";
3786 case TYPE: return "type";
3788 return "undefined type";
3792 operand *validateOpType(operand *op,
3799 if (op && op->type == type)
3804 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
3805 " expected %s, got %s\n",
3806 macro, args, file, line,
3807 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
3809 return op; // never reached, makes compiler happy.