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)));
1065 if (!options.lessPedantic &&
1066 !IS_FLOAT (OP_VALUE(retval)->type) &&
1067 !SPEC_LONG (OP_VALUE(retval)->type))
1068 ; /* TODO: werror (W_INT_OVL) */
1071 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1073 werror (E_DIVIDE_BY_ZERO);
1078 retval = operandFromValue (valCastLiteral (type,
1079 operandLitValue (left) /
1080 operandLitValue (right)));
1083 if ((TYPE_UDWORD) operandLitValue (right) == 0) {
1084 werror (E_DIVIDE_BY_ZERO);
1089 if (SPEC_USIGN(let) || SPEC_USIGN(ret))
1090 /* one of the operands is unsigned */
1091 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1092 (TYPE_UDWORD) operandLitValue (right));
1094 /* both operands are signed */
1095 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1096 (TYPE_DWORD) operandLitValue (right));
1100 /* The number of left shifts is always unsigned. Signed doesn't make
1101 sense here. Shifting by a negative number is impossible. */
1102 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1103 (TYPE_UDWORD) operandLitValue (right));
1106 /* The number of right shifts is always unsigned. Signed doesn't make
1107 sense here. Shifting by a negative number is impossible. */
1108 if (SPEC_USIGN(let))
1109 /* unsigned: logic shift right */
1110 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1111 (TYPE_UDWORD) operandLitValue (right));
1113 /* signed: arithmetic shift right */
1114 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1115 (TYPE_UDWORD) 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 = operandFromLit (operandLitValue (left) >=
1140 operandLitValue (right));
1143 retval = operandFromValue (valCastLiteral (type,
1144 (TYPE_UDWORD)operandLitValue(left) &
1145 (TYPE_UDWORD)operandLitValue(right)));
1148 retval = operandFromValue (valCastLiteral (type,
1149 (TYPE_UDWORD)operandLitValue(left) |
1150 (TYPE_UDWORD)operandLitValue(right)));
1153 retval = operandFromValue (valCastLiteral (type,
1154 (TYPE_UDWORD)operandLitValue(left) ^
1155 (TYPE_UDWORD)operandLitValue(right)));
1158 retval = operandFromLit (operandLitValue (left) &&
1159 operandLitValue (right));
1162 retval = operandFromLit (operandLitValue (left) ||
1163 operandLitValue (right));
1167 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1169 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1175 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1177 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1183 retval = operandFromLit (-1 * operandLitValue (left));
1187 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1191 retval = operandFromLit (!operandLitValue (left));
1195 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1196 " operandOperation invalid operator ");
1204 /*-----------------------------------------------------------------*/
1205 /* isOperandEqual - compares two operand & return 1 if they r = */
1206 /*-----------------------------------------------------------------*/
1208 isOperandEqual (operand * left, operand * right)
1210 /* if the pointers are equal then they are equal */
1214 /* if either of them null then false */
1215 if (!left || !right)
1218 if (left->type != right->type)
1221 if (IS_SYMOP (left) && IS_SYMOP (right))
1222 return left->key == right->key;
1224 /* if types are the same */
1228 return isSymbolEqual (left->operand.symOperand,
1229 right->operand.symOperand);
1231 return (floatFromVal (left->operand.valOperand) ==
1232 floatFromVal (right->operand.valOperand));
1234 if (compareType (left->operand.typeOperand,
1235 right->operand.typeOperand) == 1)
1242 /*-------------------------------------------------------------------*/
1243 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1244 /*-------------------------------------------------------------------*/
1246 isiCodeEqual (iCode * left, iCode * right)
1248 /* if the same pointer */
1252 /* if either of them null */
1253 if (!left || !right)
1256 /* if operand are the same */
1257 if (left->op == right->op)
1260 /* compare all the elements depending on type */
1261 if (left->op != IFX)
1263 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1265 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1271 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1273 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1275 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1284 /*-----------------------------------------------------------------*/
1285 /* newiTempFromOp - create a temp Operand with same attributes */
1286 /*-----------------------------------------------------------------*/
1288 newiTempFromOp (operand * op)
1298 nop = newiTempOperand (operandType (op), TRUE);
1299 nop->isaddr = op->isaddr;
1300 nop->isvolatile = op->isvolatile;
1301 nop->isGlobal = op->isGlobal;
1302 nop->isLiteral = op->isLiteral;
1303 nop->usesDefs = op->usesDefs;
1304 nop->isParm = op->isParm;
1308 /*-----------------------------------------------------------------*/
1309 /* operand from operand - creates an operand holder for the type */
1310 /*-----------------------------------------------------------------*/
1312 operandFromOperand (operand * op)
1318 nop = newOperand ();
1319 nop->type = op->type;
1320 nop->isaddr = op->isaddr;
1322 nop->isvolatile = op->isvolatile;
1323 nop->isGlobal = op->isGlobal;
1324 nop->isLiteral = op->isLiteral;
1325 nop->usesDefs = op->usesDefs;
1326 nop->isParm = op->isParm;
1331 nop->operand.symOperand = op->operand.symOperand;
1334 nop->operand.valOperand = op->operand.valOperand;
1337 nop->operand.typeOperand = op->operand.typeOperand;
1344 /*-----------------------------------------------------------------*/
1345 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1346 /*-----------------------------------------------------------------*/
1348 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1350 operand *nop = operandFromOperand (op);
1352 if (nop->type == SYMBOL)
1354 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1355 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1361 /*-----------------------------------------------------------------*/
1362 /* operandFromSymbol - creates an operand from a symbol */
1363 /*-----------------------------------------------------------------*/
1365 operandFromSymbol (symbol * sym)
1370 /* if the symbol's type is a literal */
1371 /* then it is an enumerator type */
1372 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1373 return operandFromValue (valFromType (sym->etype));
1376 sym->key = ++operandKey;
1378 /* if this an implicit variable, means struct/union */
1379 /* member so just return it */
1380 if (sym->implicit || IS_FUNC (sym->type))
1384 op->operand.symOperand = sym;
1386 op->isvolatile = isOperandVolatile (op, TRUE);
1387 op->isGlobal = isOperandGlobal (op);
1391 /* under the following conditions create a
1392 register equivalent for a local symbol */
1393 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1394 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1395 (!(options.model == MODEL_FLAT24)) ) &&
1396 options.stackAuto == 0)
1399 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1400 !IS_FUNC (sym->type) && /* not a function */
1401 !sym->_isparm && /* not a parameter */
1402 sym->level && /* is a local variable */
1403 !sym->addrtaken && /* whose address has not been taken */
1404 !sym->reqv && /* does not already have a reg equivalence */
1405 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1406 !IS_STATIC (sym->etype) && /* and not declared static */
1407 !sym->islbl && /* not a label */
1408 ok && /* farspace check */
1409 !IS_BITVAR (sym->etype) /* not a bit variable */
1413 /* we will use it after all optimizations
1414 and before liveRange calculation */
1415 sym->reqv = newiTempOperand (sym->type, 0);
1416 sym->reqv->key = sym->key;
1417 OP_SYMBOL (sym->reqv)->key = sym->key;
1418 OP_SYMBOL (sym->reqv)->isreqv = 1;
1419 OP_SYMBOL (sym->reqv)->islocal = 1;
1420 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1421 SPIL_LOC (sym->reqv) = sym;
1424 if (!IS_AGGREGATE (sym->type))
1428 op->operand.symOperand = sym;
1431 op->isvolatile = isOperandVolatile (op, TRUE);
1432 op->isGlobal = isOperandGlobal (op);
1433 op->isPtr = IS_PTR (operandType (op));
1434 op->isParm = sym->_isparm;
1439 /* itemp = &[_symbol] */
1441 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1442 IC_LEFT (ic)->type = SYMBOL;
1443 IC_LEFT (ic)->operand.symOperand = sym;
1444 IC_LEFT (ic)->key = sym->key;
1445 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1446 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1447 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1450 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1451 if (IS_ARRAY (sym->type))
1453 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1454 IC_RESULT (ic)->isaddr = 0;
1457 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1461 return IC_RESULT (ic);
1464 /*-----------------------------------------------------------------*/
1465 /* operandFromValue - creates an operand from value */
1466 /*-----------------------------------------------------------------*/
1468 operandFromValue (value * val)
1472 /* if this is a symbol then do the symbol thing */
1474 return operandFromSymbol (val->sym);
1476 /* this is not a symbol */
1479 op->operand.valOperand = val;
1480 op->isLiteral = isOperandLiteral (op);
1484 /*-----------------------------------------------------------------*/
1485 /* operandFromLink - operand from typeChain */
1486 /*-----------------------------------------------------------------*/
1488 operandFromLink (sym_link * type)
1492 /* operand from sym_link */
1498 op->operand.typeOperand = copyLinkChain (type);
1502 /*-----------------------------------------------------------------*/
1503 /* operandFromLit - makes an operand from a literal value */
1504 /*-----------------------------------------------------------------*/
1506 operandFromLit (double i)
1508 return operandFromValue (valueFromLit (i));
1511 /*-----------------------------------------------------------------*/
1512 /* operandFromAst - creates an operand from an ast */
1513 /*-----------------------------------------------------------------*/
1515 operandFromAst (ast * tree,int lvl)
1521 /* depending on type do */
1525 return ast2iCode (tree,lvl+1);
1529 return operandFromValue (tree->opval.val);
1533 return operandFromLink (tree->opval.lnk);
1540 /* Just to keep the compiler happy */
1541 return (operand *) 0;
1544 /*-----------------------------------------------------------------*/
1545 /* setOperandType - sets the operand's type to the given type */
1546 /*-----------------------------------------------------------------*/
1548 setOperandType (operand * op, sym_link * type)
1550 /* depending on the type of operand */
1555 op->operand.valOperand->etype =
1556 getSpec (op->operand.valOperand->type =
1557 copyLinkChain (type));
1561 if (op->operand.symOperand->isitmp)
1562 op->operand.symOperand->etype =
1563 getSpec (op->operand.symOperand->type =
1564 copyLinkChain (type));
1566 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1567 "attempt to modify type of source");
1571 op->operand.typeOperand = copyLinkChain (type);
1576 /*-----------------------------------------------------------------*/
1577 /* Get size in byte of ptr need to access an array */
1578 /*-----------------------------------------------------------------*/
1580 getArraySizePtr (operand * op)
1582 sym_link *ltype = operandType(op);
1586 int size = getSize(ltype);
1587 return(IS_GENPTR(ltype)?(size-1):size);
1592 sym_link *letype = getSpec(ltype);
1593 switch (PTR_TYPE (SPEC_OCLS (letype)))
1605 return (GPTRSIZE-1);
1614 /*-----------------------------------------------------------------*/
1615 /* perform "usual unary conversions" */
1616 /*-----------------------------------------------------------------*/
1618 usualUnaryConversions (operand * op)
1620 if (IS_INTEGRAL (operandType (op)))
1622 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1625 return geniCodeCast (INTTYPE, op, TRUE);
1631 /*-----------------------------------------------------------------*/
1632 /* perform "usual binary conversions" */
1633 /*-----------------------------------------------------------------*/
1635 usualBinaryConversions (operand ** op1, operand ** op2)
1638 sym_link *rtype = operandType (*op2);
1639 sym_link *ltype = operandType (*op1);
1641 ctype = computeType (ltype, rtype);
1643 *op1 = geniCodeCast (ctype, *op1, TRUE);
1644 *op2 = geniCodeCast (ctype, *op2, TRUE);
1649 /*-----------------------------------------------------------------*/
1650 /* geniCodeValueAtAddress - generate intermeditate code for value */
1652 /*-----------------------------------------------------------------*/
1654 geniCodeRValue (operand * op, bool force)
1657 sym_link *type = operandType (op);
1658 sym_link *etype = getSpec (type);
1660 /* if this is an array & already */
1661 /* an address then return this */
1662 if (IS_AGGREGATE (type) ||
1663 (IS_PTR (type) && !force && !op->isaddr))
1664 return operandFromOperand (op);
1666 /* if this is not an address then must be */
1667 /* rvalue already so return this one */
1671 /* if this is not a temp symbol then */
1672 if (!IS_ITEMP (op) &&
1674 !IN_FARSPACE (SPEC_OCLS (etype)))
1676 op = operandFromOperand (op);
1681 if (IS_SPEC (type) &&
1682 IS_TRUE_SYMOP (op) &&
1683 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1684 (options.model == MODEL_FLAT24) ))
1686 op = operandFromOperand (op);
1691 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1692 if (IS_PTR (type) && op->isaddr && force)
1695 type = copyLinkChain (type);
1697 IC_RESULT (ic) = newiTempOperand (type, 1);
1698 IC_RESULT (ic)->isaddr = 0;
1700 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1704 return IC_RESULT (ic);
1707 /*-----------------------------------------------------------------*/
1708 /* geniCodeCast - changes the value from one type to another */
1709 /*-----------------------------------------------------------------*/
1711 geniCodeCast (sym_link * type, operand * op, bool implicit)
1715 sym_link *opetype = getSpec (optype = operandType (op));
1719 /* one of them has size zero then error */
1720 if (IS_VOID (optype))
1722 werror (E_CAST_ZERO);
1726 /* if the operand is already the desired type then do nothing */
1727 if (compareType (type, optype) == 1)
1730 /* if this is a literal then just change the type & return */
1731 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1732 return operandFromValue (valCastLiteral (type,
1733 operandLitValue (op)));
1735 /* if casting to/from pointers, do some checking */
1736 if (IS_PTR(type)) { // to a pointer
1737 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1738 if (IS_INTEGRAL(optype)) {
1739 // maybe this is NULL, than it's ok.
1740 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1741 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1742 // no way to set the storage
1743 if (IS_LITERAL(optype)) {
1744 werror(E_LITERAL_GENERIC);
1747 werror(E_NONPTR2_GENPTR);
1750 } else if (implicit) {
1751 werror(W_INTEGRAL2PTR_NOCAST);
1756 // shouldn't do that with float, array or structure unless to void
1757 if (!IS_VOID(getSpec(type)) &&
1758 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1759 werror(E_INCOMPAT_TYPES);
1763 } else { // from a pointer to a pointer
1764 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1765 // if not a pointer to a function
1766 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1767 if (implicit) { // if not to generic, they have to match
1768 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1769 werror(E_INCOMPAT_PTYPES);
1776 } else { // to a non pointer
1777 if (IS_PTR(optype)) { // from a pointer
1778 if (implicit) { // sneaky
1779 if (IS_INTEGRAL(type)) {
1780 werror(W_PTR2INTEGRAL_NOCAST);
1782 } else { // shouldn't do that with float, array or structure
1783 werror(E_INCOMPAT_TYPES);
1790 printFromToType (optype, type);
1793 /* if they are the same size create an assignment */
1794 if (getSize (type) == getSize (optype) &&
1795 !IS_BITFIELD (type) &&
1797 !IS_FLOAT (optype) &&
1798 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1799 (!IS_SPEC (type) && !IS_SPEC (optype))))
1802 ic = newiCode ('=', NULL, op);
1803 IC_RESULT (ic) = newiTempOperand (type, 0);
1804 SPIL_LOC (IC_RESULT (ic)) =
1805 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1806 IC_RESULT (ic)->isaddr = 0;
1810 ic = newiCode (CAST, operandFromLink (type),
1811 geniCodeRValue (op, FALSE));
1813 IC_RESULT (ic) = newiTempOperand (type, 0);
1816 /* preserve the storage class & output class */
1817 /* of the original variable */
1818 restype = getSpec (operandType (IC_RESULT (ic)));
1819 if (!IS_LITERAL(opetype))
1820 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1821 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1824 return IC_RESULT (ic);
1827 /*-----------------------------------------------------------------*/
1828 /* geniCodeLabel - will create a Label */
1829 /*-----------------------------------------------------------------*/
1831 geniCodeLabel (symbol * label)
1835 ic = newiCodeLabelGoto (LABEL, label);
1839 /*-----------------------------------------------------------------*/
1840 /* geniCodeGoto - will create a Goto */
1841 /*-----------------------------------------------------------------*/
1843 geniCodeGoto (symbol * label)
1847 ic = newiCodeLabelGoto (GOTO, label);
1851 /*-----------------------------------------------------------------*/
1852 /* geniCodeMultiply - gen intermediate code for multiplication */
1853 /*-----------------------------------------------------------------*/
1855 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1862 /* if they are both literal then we know the result */
1863 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1864 return operandFromValue (valMult (left->operand.valOperand,
1865 right->operand.valOperand));
1867 if (IS_LITERAL(retype)) {
1868 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1871 resType = usualBinaryConversions (&left, &right);
1873 rtype = operandType (right);
1874 retype = getSpec (rtype);
1875 ltype = operandType (left);
1876 letype = getSpec (ltype);
1880 SPEC_NOUN(getSpec(resType))=V_INT;
1883 /* if the right is a literal & power of 2 */
1884 /* then make it a left shift */
1885 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1886 efficient in most cases than 2 bytes result = 2 bytes << literal
1887 if port has 1 byte muldiv */
1888 if (p2 && !IS_FLOAT (letype) &&
1889 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1890 (port->support.muldiv == 1)))
1892 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1894 /* LEFT_OP need same size for left and result, */
1895 left = geniCodeCast (resType, left, TRUE);
1896 ltype = operandType (left);
1898 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1902 ic = newiCode ('*', left, right); /* normal multiplication */
1903 /* if the size left or right > 1 then support routine */
1904 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1908 IC_RESULT (ic) = newiTempOperand (resType, 1);
1911 return IC_RESULT (ic);
1914 /*-----------------------------------------------------------------*/
1915 /* geniCodeDivision - gen intermediate code for division */
1916 /*-----------------------------------------------------------------*/
1918 geniCodeDivision (operand * left, operand * right)
1923 sym_link *rtype = operandType (right);
1924 sym_link *retype = getSpec (rtype);
1925 sym_link *ltype = operandType (left);
1926 sym_link *letype = getSpec (ltype);
1928 resType = usualBinaryConversions (&left, &right);
1930 /* if the right is a literal & power of 2
1931 and left is unsigned then make it a
1933 if (IS_LITERAL (retype) &&
1934 !IS_FLOAT (letype) &&
1935 SPEC_USIGN(letype) &&
1936 (p2 = powof2 ((unsigned long)
1937 floatFromVal (right->operand.valOperand)))) {
1938 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1942 ic = newiCode ('/', left, right); /* normal division */
1943 /* if the size left or right > 1 then support routine */
1944 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1947 IC_RESULT (ic) = newiTempOperand (resType, 0);
1950 return IC_RESULT (ic);
1952 /*-----------------------------------------------------------------*/
1953 /* geniCodeModulus - gen intermediate code for modulus */
1954 /*-----------------------------------------------------------------*/
1956 geniCodeModulus (operand * left, operand * right)
1962 /* if they are both literal then we know the result */
1963 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1964 return operandFromValue (valMod (left->operand.valOperand,
1965 right->operand.valOperand));
1967 resType = usualBinaryConversions (&left, &right);
1969 /* now they are the same size */
1970 ic = newiCode ('%', left, right);
1972 /* if the size left or right > 1 then support routine */
1973 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1975 IC_RESULT (ic) = newiTempOperand (resType, 0);
1978 return IC_RESULT (ic);
1981 /*-----------------------------------------------------------------*/
1982 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1983 /*-----------------------------------------------------------------*/
1985 geniCodePtrPtrSubtract (operand * left, operand * right)
1991 /* if they are both literals then */
1992 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1994 result = operandFromValue (valMinus (left->operand.valOperand,
1995 right->operand.valOperand));
1999 ic = newiCode ('-', left, right);
2001 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2005 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2009 // should we really do this? is this ANSI?
2010 return geniCodeDivision (result,
2011 operandFromLit (getSize (ltype->next)));
2014 /*-----------------------------------------------------------------*/
2015 /* geniCodeSubtract - generates code for subtraction */
2016 /*-----------------------------------------------------------------*/
2018 geniCodeSubtract (operand * left, operand * right)
2025 /* if they both pointers then */
2026 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2027 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2028 return geniCodePtrPtrSubtract (left, right);
2030 /* if they are both literal then we know the result */
2031 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2032 && left->isLiteral && right->isLiteral)
2033 return operandFromValue (valMinus (left->operand.valOperand,
2034 right->operand.valOperand));
2036 /* if left is an array or pointer */
2037 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2039 isarray = left->isaddr;
2040 right = geniCodeMultiply (right,
2041 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2042 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2045 { /* make them the same size */
2046 resType = usualBinaryConversions (&left, &right);
2049 ic = newiCode ('-', left, right);
2051 IC_RESULT (ic) = newiTempOperand (resType, 1);
2052 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2054 /* if left or right is a float */
2055 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2059 return IC_RESULT (ic);
2062 /*-----------------------------------------------------------------*/
2063 /* geniCodeAdd - generates iCode for addition */
2064 /*-----------------------------------------------------------------*/
2066 geniCodeAdd (operand * left, operand * right, int lvl)
2074 /* if the right side is LITERAL zero */
2075 /* return the left side */
2076 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2079 /* if left is literal zero return right */
2080 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2083 /* if left is a pointer then size */
2084 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2086 isarray = left->isaddr;
2087 // there is no need to multiply with 1
2088 if (getSize(ltype->next)!=1) {
2089 size = operandFromLit (getSize (ltype->next));
2090 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2092 resType = copyLinkChain (ltype);
2095 { // make them the same size
2096 resType = usualBinaryConversions (&left, &right);
2099 /* if they are both literals then we know */
2100 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2101 && left->isLiteral && right->isLiteral)
2102 return operandFromValue (valPlus (valFromType (letype),
2103 valFromType (retype)));
2105 ic = newiCode ('+', left, right);
2107 IC_RESULT (ic) = newiTempOperand (resType, 1);
2108 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2110 /* if left or right is a float then support
2112 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2117 return IC_RESULT (ic);
2121 /*-----------------------------------------------------------------*/
2122 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2123 /*-----------------------------------------------------------------*/
2125 aggrToPtr (sym_link * type, bool force)
2131 if (IS_PTR (type) && !force)
2134 etype = getSpec (type);
2135 ptype = newLink (DECLARATOR);
2139 /* if the output class is code */
2140 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2141 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2143 /* if the variable was declared a constant */
2144 /* then the pointer points to a constant */
2145 if (IS_CONSTANT (etype))
2146 DCL_PTR_CONST (ptype) = 1;
2148 /* the variable was volatile then pointer to volatile */
2149 if (IS_VOLATILE (etype))
2150 DCL_PTR_VOLATILE (ptype) = 1;
2155 /*-----------------------------------------------------------------*/
2156 /* geniCodeArray2Ptr - array to pointer */
2157 /*-----------------------------------------------------------------*/
2159 geniCodeArray2Ptr (operand * op)
2161 sym_link *optype = operandType (op);
2162 sym_link *opetype = getSpec (optype);
2164 /* set the pointer depending on the storage class */
2165 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2166 DCL_PTR_CONST (optype) = port->mem.code_ro;
2168 /* if the variable was declared a constant */
2169 /* then the pointer points to a constant */
2170 if (IS_CONSTANT (opetype))
2171 DCL_PTR_CONST (optype) = 1;
2173 /* the variable was volatile then pointer to volatile */
2174 if (IS_VOLATILE (opetype))
2175 DCL_PTR_VOLATILE (optype) = 1;
2182 /*-----------------------------------------------------------------*/
2183 /* geniCodeArray - array access */
2184 /*-----------------------------------------------------------------*/
2186 geniCodeArray (operand * left, operand * right,int lvl)
2189 sym_link *ltype = operandType (left);
2193 if (IS_PTR (ltype->next) && left->isaddr)
2195 left = geniCodeRValue (left, FALSE);
2197 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2200 right = geniCodeMultiply (right,
2201 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2203 /* we can check for limits here */
2204 if (isOperandLiteral (right) &&
2207 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2209 werror (E_ARRAY_BOUND);
2210 right = operandFromLit (0);
2213 ic = newiCode ('+', left, right);
2215 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2216 !IS_AGGREGATE (ltype->next) &&
2217 !IS_PTR (ltype->next))
2218 ? ltype : ltype->next), 0);
2220 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2222 return IC_RESULT (ic);
2225 /*-----------------------------------------------------------------*/
2226 /* geniCodeStruct - generates intermediate code for structres */
2227 /*-----------------------------------------------------------------*/
2229 geniCodeStruct (operand * left, operand * right, bool islval)
2232 sym_link *type = operandType (left);
2233 sym_link *etype = getSpec (type);
2235 symbol *element = getStructElement (SPEC_STRUCT (etype),
2236 right->operand.symOperand);
2238 wassert(IS_SYMOP(right));
2240 /* add the offset */
2241 ic = newiCode ('+', left, operandFromLit (element->offset));
2243 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2245 /* preserve the storage & output class of the struct */
2246 /* as well as the volatile attribute */
2247 retype = getSpec (operandType (IC_RESULT (ic)));
2248 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2249 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2250 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2252 if (IS_PTR (element->type))
2253 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2255 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2259 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2262 /*-----------------------------------------------------------------*/
2263 /* geniCodePostInc - generate int code for Post increment */
2264 /*-----------------------------------------------------------------*/
2266 geniCodePostInc (operand * op)
2270 sym_link *optype = operandType (op);
2272 operand *rv = (IS_ITEMP (op) ?
2273 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2275 sym_link *rvtype = operandType (rv);
2278 /* if this is not an address we have trouble */
2281 werror (E_LVALUE_REQUIRED, "++");
2285 rOp = newiTempOperand (rvtype, 0);
2286 OP_SYMBOL(rOp)->noSpilLoc = 1;
2289 OP_SYMBOL(rv)->noSpilLoc = 1;
2291 geniCodeAssign (rOp, rv, 0);
2293 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2294 if (IS_FLOAT (rvtype))
2295 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2297 ic = newiCode ('+', rv, operandFromLit (size));
2299 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2302 geniCodeAssign (op, result, 0);
2308 /*-----------------------------------------------------------------*/
2309 /* geniCodePreInc - generate code for preIncrement */
2310 /*-----------------------------------------------------------------*/
2312 geniCodePreInc (operand * op)
2315 sym_link *optype = operandType (op);
2316 operand *rop = (IS_ITEMP (op) ?
2317 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2319 sym_link *roptype = operandType (rop);
2325 werror (E_LVALUE_REQUIRED, "++");
2330 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2331 if (IS_FLOAT (roptype))
2332 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2334 ic = newiCode ('+', rop, operandFromLit (size));
2335 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2339 return geniCodeAssign (op, result, 0);
2342 /*-----------------------------------------------------------------*/
2343 /* geniCodePostDec - generates code for Post decrement */
2344 /*-----------------------------------------------------------------*/
2346 geniCodePostDec (operand * op)
2350 sym_link *optype = operandType (op);
2352 operand *rv = (IS_ITEMP (op) ?
2353 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2355 sym_link *rvtype = operandType (rv);
2358 /* if this is not an address we have trouble */
2361 werror (E_LVALUE_REQUIRED, "--");
2365 rOp = newiTempOperand (rvtype, 0);
2366 OP_SYMBOL(rOp)->noSpilLoc = 1;
2369 OP_SYMBOL(rv)->noSpilLoc = 1;
2371 geniCodeAssign (rOp, rv, 0);
2373 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2374 if (IS_FLOAT (rvtype))
2375 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2377 ic = newiCode ('-', rv, operandFromLit (size));
2379 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2382 geniCodeAssign (op, result, 0);
2388 /*-----------------------------------------------------------------*/
2389 /* geniCodePreDec - generate code for pre decrement */
2390 /*-----------------------------------------------------------------*/
2392 geniCodePreDec (operand * op)
2395 sym_link *optype = operandType (op);
2396 operand *rop = (IS_ITEMP (op) ?
2397 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2399 sym_link *roptype = operandType (rop);
2405 werror (E_LVALUE_REQUIRED, "--");
2410 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2411 if (IS_FLOAT (roptype))
2412 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2414 ic = newiCode ('-', rop, operandFromLit (size));
2415 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2419 return geniCodeAssign (op, result, 0);
2423 /*-----------------------------------------------------------------*/
2424 /* geniCodeBitwise - gen int code for bitWise operators */
2425 /*-----------------------------------------------------------------*/
2427 geniCodeBitwise (operand * left, operand * right,
2428 int oper, sym_link * resType)
2432 left = geniCodeCast (resType, left, TRUE);
2433 right = geniCodeCast (resType, right, TRUE);
2435 ic = newiCode (oper, left, right);
2436 IC_RESULT (ic) = newiTempOperand (resType, 0);
2439 return IC_RESULT (ic);
2442 /*-----------------------------------------------------------------*/
2443 /* geniCodeAddressOf - gens icode for '&' address of operator */
2444 /*-----------------------------------------------------------------*/
2446 geniCodeAddressOf (operand * op)
2450 sym_link *optype = operandType (op);
2451 sym_link *opetype = getSpec (optype);
2453 /* lvalue check already done in decorateType */
2454 /* this must be a lvalue */
2455 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2456 /* werror (E_LVALUE_REQUIRED,"&"); */
2460 p = newLink (DECLARATOR);
2462 /* set the pointer depending on the storage class */
2463 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2464 DCL_PTR_CONST (p) = port->mem.code_ro;
2466 /* make sure we preserve the const & volatile */
2467 if (IS_CONSTANT (opetype))
2468 DCL_PTR_CONST (p) = 1;
2470 if (IS_VOLATILE (opetype))
2471 DCL_PTR_VOLATILE (p) = 1;
2473 p->next = copyLinkChain (optype);
2475 /* if already a temp */
2478 setOperandType (op, p);
2483 /* other wise make this of the type coming in */
2484 ic = newiCode (ADDRESS_OF, op, NULL);
2485 IC_RESULT (ic) = newiTempOperand (p, 1);
2486 IC_RESULT (ic)->isaddr = 0;
2488 return IC_RESULT (ic);
2490 /*-----------------------------------------------------------------*/
2491 /* setOClass - sets the output class depending on the pointer type */
2492 /*-----------------------------------------------------------------*/
2494 setOClass (sym_link * ptr, sym_link * spec)
2496 switch (DCL_TYPE (ptr))
2499 SPEC_OCLS (spec) = data;
2503 SPEC_OCLS (spec) = generic;
2507 SPEC_OCLS (spec) = xdata;
2511 SPEC_OCLS (spec) = code;
2515 SPEC_OCLS (spec) = idata;
2519 SPEC_OCLS (spec) = xstack;
2523 SPEC_OCLS (spec) = eeprom;
2532 /*-----------------------------------------------------------------*/
2533 /* geniCodeDerefPtr - dereference pointer with '*' */
2534 /*-----------------------------------------------------------------*/
2536 geniCodeDerefPtr (operand * op,int lvl)
2538 sym_link *rtype, *retype;
2539 sym_link *optype = operandType (op);
2541 // if this is an array then array access
2542 if (IS_ARRAY (optype)) {
2543 // don't worry, this will be optimized out later
2544 return geniCodeArray (op, operandFromLit (0), lvl);
2547 // just in case someone screws up
2548 wassert (IS_PTR (optype));
2550 if (IS_TRUE_SYMOP (op))
2553 op = geniCodeRValue (op, TRUE);
2556 /* now get rid of the pointer part */
2557 if (isLvaluereq(lvl) && IS_ITEMP (op))
2559 retype = getSpec (rtype = copyLinkChain (optype));
2563 retype = getSpec (rtype = copyLinkChain (optype->next));
2566 /* outputclass needs 2b updated */
2567 setOClass (optype, retype);
2569 op->isGptr = IS_GENPTR (optype);
2571 /* if the pointer was declared as a constant */
2572 /* then we cannot allow assignment to the derefed */
2573 if (IS_PTR_CONST (optype))
2574 SPEC_CONST (retype) = 1;
2576 op->isaddr = (IS_PTR (rtype) ||
2577 IS_STRUCT (rtype) ||
2582 if (!isLvaluereq(lvl))
2583 op = geniCodeRValue (op, TRUE);
2585 setOperandType (op, rtype);
2590 /*-----------------------------------------------------------------*/
2591 /* geniCodeUnaryMinus - does a unary minus of the operand */
2592 /*-----------------------------------------------------------------*/
2594 geniCodeUnaryMinus (operand * op)
2597 sym_link *optype = operandType (op);
2599 if (IS_LITERAL (optype))
2600 return operandFromLit (-floatFromVal (op->operand.valOperand));
2602 ic = newiCode (UNARYMINUS, op, NULL);
2603 IC_RESULT (ic) = newiTempOperand (optype, 0);
2605 return IC_RESULT (ic);
2608 /*-----------------------------------------------------------------*/
2609 /* geniCodeLeftShift - gen i code for left shift */
2610 /*-----------------------------------------------------------------*/
2612 geniCodeLeftShift (operand * left, operand * right)
2616 ic = newiCode (LEFT_OP, left, right);
2617 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2619 return IC_RESULT (ic);
2622 /*-----------------------------------------------------------------*/
2623 /* geniCodeRightShift - gen i code for right shift */
2624 /*-----------------------------------------------------------------*/
2626 geniCodeRightShift (operand * left, operand * right)
2630 ic = newiCode (RIGHT_OP, left, right);
2631 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2633 return IC_RESULT (ic);
2636 /*-----------------------------------------------------------------*/
2637 /* geniCodeLogic- logic code */
2638 /*-----------------------------------------------------------------*/
2640 geniCodeLogic (operand * left, operand * right, int op)
2644 sym_link *rtype = operandType (right);
2645 sym_link *ltype = operandType (left);
2647 /* left is integral type and right is literal then
2648 check if the literal value is within bounds */
2649 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2651 checkConstantRange(ltype,
2652 OP_VALUE(right), "compare operation", 1);
2655 ctype = usualBinaryConversions (&left, &right);
2657 ic = newiCode (op, left, right);
2658 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2660 /* if comparing float
2661 and not a '==' || '!=' || '&&' || '||' (these
2663 if (IS_FLOAT(ctype) &&
2671 return IC_RESULT (ic);
2674 /*-----------------------------------------------------------------*/
2675 /* geniCodeUnary - for a a generic unary operation */
2676 /*-----------------------------------------------------------------*/
2678 geniCodeUnary (operand * op, int oper)
2680 iCode *ic = newiCode (oper, op, NULL);
2682 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2684 return IC_RESULT (ic);
2687 /*-----------------------------------------------------------------*/
2688 /* geniCodeConditional - geniCode for '?' ':' operation */
2689 /*-----------------------------------------------------------------*/
2691 geniCodeConditional (ast * tree,int lvl)
2694 symbol *falseLabel = newiTempLabel (NULL);
2695 symbol *exitLabel = newiTempLabel (NULL);
2696 operand *cond = ast2iCode (tree->left,lvl+1);
2697 operand *true, *false, *result;
2699 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2703 true = ast2iCode (tree->right->left,lvl+1);
2705 /* move the value to a new Operand */
2706 result = newiTempOperand (tree->right->ftype, 0);
2707 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2709 /* generate an unconditional goto */
2710 geniCodeGoto (exitLabel);
2712 /* now for the right side */
2713 geniCodeLabel (falseLabel);
2715 false = ast2iCode (tree->right->right,lvl+1);
2716 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2718 /* create the exit label */
2719 geniCodeLabel (exitLabel);
2724 /*-----------------------------------------------------------------*/
2725 /* geniCodeAssign - generate code for assignment */
2726 /*-----------------------------------------------------------------*/
2728 geniCodeAssign (operand * left, operand * right, int nosupdate)
2731 sym_link *ltype = operandType (left);
2732 sym_link *rtype = operandType (right);
2734 if (!left->isaddr && !IS_ITEMP (left))
2736 werror (E_LVALUE_REQUIRED, "assignment");
2740 /* left is integral type and right is literal then
2741 check if the literal value is within bounds */
2742 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2744 checkConstantRange(ltype,
2745 OP_VALUE(right), "= operation", 0);
2748 /* if the left & right type don't exactly match */
2749 /* if pointer set then make sure the check is
2750 done with the type & not the pointer */
2751 /* then cast rights type to left */
2753 /* first check the type for pointer assignement */
2754 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2755 compareType (ltype, rtype) <= 0)
2757 if (compareType (ltype->next, rtype) < 0)
2758 right = geniCodeCast (ltype->next, right, TRUE);
2760 else if (compareType (ltype, rtype) < 0)
2761 right = geniCodeCast (ltype, right, TRUE);
2763 /* if left is a true symbol & ! volatile
2764 create an assignment to temporary for
2765 the right & then assign this temporary
2766 to the symbol this is SSA . isn't it simple
2767 and folks have published mountains of paper on it */
2768 if (IS_TRUE_SYMOP (left) &&
2769 !isOperandVolatile (left, FALSE) &&
2770 isOperandGlobal (left))
2774 if (IS_TRUE_SYMOP (right))
2775 sym = OP_SYMBOL (right);
2776 ic = newiCode ('=', NULL, right);
2777 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2778 SPIL_LOC (right) = sym;
2782 ic = newiCode ('=', NULL, right);
2783 IC_RESULT (ic) = left;
2786 /* if left isgptr flag is set then support
2787 routine will be required */
2791 ic->nosupdate = nosupdate;
2795 /*-----------------------------------------------------------------*/
2796 /* geniCodeSEParms - generate code for side effecting fcalls */
2797 /*-----------------------------------------------------------------*/
2799 geniCodeSEParms (ast * parms,int lvl)
2804 if (parms->type == EX_OP && parms->opval.op == PARAM)
2806 geniCodeSEParms (parms->left,lvl);
2807 geniCodeSEParms (parms->right,lvl);
2811 /* hack don't like this but too lazy to think of
2813 if (IS_ADDRESS_OF_OP (parms))
2814 parms->left->lvalue = 1;
2816 if (IS_CAST_OP (parms) &&
2817 IS_PTR (parms->ftype) &&
2818 IS_ADDRESS_OF_OP (parms->right))
2819 parms->right->left->lvalue = 1;
2821 parms->opval.oprnd =
2822 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2824 parms->type = EX_OPERAND;
2825 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2826 SPEC_ARGREG(parms->ftype);
2829 /*-----------------------------------------------------------------*/
2830 /* geniCodeParms - generates parameters */
2831 /*-----------------------------------------------------------------*/
2833 geniCodeParms (ast * parms, value *argVals, int *stack,
2834 sym_link * fetype, symbol * func,int lvl)
2842 if (argVals==NULL) {
2844 argVals=FUNC_ARGS(func->type);
2847 /* if this is a param node then do the left & right */
2848 if (parms->type == EX_OP && parms->opval.op == PARAM)
2850 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2851 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2855 /* get the parameter value */
2856 if (parms->type == EX_OPERAND)
2857 pval = parms->opval.oprnd;
2860 /* maybe this else should go away ?? */
2861 /* hack don't like this but too lazy to think of
2863 if (IS_ADDRESS_OF_OP (parms))
2864 parms->left->lvalue = 1;
2866 if (IS_CAST_OP (parms) &&
2867 IS_PTR (parms->ftype) &&
2868 IS_ADDRESS_OF_OP (parms->right))
2869 parms->right->left->lvalue = 1;
2871 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2874 /* if register parm then make it a send */
2875 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2876 IFFUNC_ISBUILTIN(func->type))
2878 ic = newiCode (SEND, pval, NULL);
2879 ic->argreg = SPEC_ARGREG(parms->etype);
2880 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2885 /* now decide whether to push or assign */
2886 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2890 operand *top = operandFromSymbol (argVals->sym);
2891 /* clear useDef and other bitVectors */
2892 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
2893 geniCodeAssign (top, pval, 1);
2897 sym_link *p = operandType (pval);
2899 ic = newiCode (IPUSH, pval, NULL);
2901 /* update the stack adjustment */
2902 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2907 argVals=argVals->next;
2911 /*-----------------------------------------------------------------*/
2912 /* geniCodeCall - generates temp code for calling */
2913 /*-----------------------------------------------------------------*/
2915 geniCodeCall (operand * left, ast * parms,int lvl)
2919 sym_link *type, *etype;
2922 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2923 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2924 werror (E_FUNCTION_EXPECTED);
2928 /* take care of parameters with side-effecting
2929 function calls in them, this is required to take care
2930 of overlaying function parameters */
2931 geniCodeSEParms (parms,lvl);
2933 /* first the parameters */
2934 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2936 /* now call : if symbol then pcall */
2937 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
2938 ic = newiCode (PCALL, left, NULL);
2940 ic = newiCode (CALL, left, NULL);
2943 type = copyLinkChain (operandType (left)->next);
2944 etype = getSpec (type);
2945 SPEC_EXTR (etype) = 0;
2946 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2950 /* stack adjustment after call */
2951 ic->parmBytes = stack;
2956 /*-----------------------------------------------------------------*/
2957 /* geniCodeReceive - generate intermediate code for "receive" */
2958 /*-----------------------------------------------------------------*/
2960 geniCodeReceive (value * args)
2962 /* for all arguments that are passed in registers */
2966 if (IS_REGPARM (args->etype))
2968 operand *opr = operandFromValue (args);
2970 symbol *sym = OP_SYMBOL (opr);
2973 /* we will use it after all optimizations
2974 and before liveRange calculation */
2975 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2978 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2979 options.stackAuto == 0 &&
2980 (!(options.model == MODEL_FLAT24)) )
2985 opl = newiTempOperand (args->type, 0);
2987 sym->reqv->key = sym->key;
2988 OP_SYMBOL (sym->reqv)->key = sym->key;
2989 OP_SYMBOL (sym->reqv)->isreqv = 1;
2990 OP_SYMBOL (sym->reqv)->islocal = 0;
2991 SPIL_LOC (sym->reqv) = sym;
2995 ic = newiCode (RECEIVE, NULL, NULL);
2996 ic->argreg = SPEC_ARGREG(args->etype);
2998 currFunc->recvSize = getSize (sym->type);
3001 IC_RESULT (ic) = opr;
3009 /*-----------------------------------------------------------------*/
3010 /* geniCodeFunctionBody - create the function body */
3011 /*-----------------------------------------------------------------*/
3013 geniCodeFunctionBody (ast * tree,int lvl)
3020 /* reset the auto generation */
3026 func = ast2iCode (tree->left,lvl+1);
3027 fetype = getSpec (operandType (func));
3029 savelineno = lineno;
3030 lineno = OP_SYMBOL (func)->lineDef;
3031 /* create an entry label */
3032 geniCodeLabel (entryLabel);
3033 lineno = savelineno;
3035 /* create a proc icode */
3036 ic = newiCode (FUNCTION, func, NULL);
3037 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3041 /* for all parameters that are passed
3042 on registers add a "receive" */
3043 geniCodeReceive (tree->values.args);
3045 /* generate code for the body */
3046 ast2iCode (tree->right,lvl+1);
3048 /* create a label for return */
3049 geniCodeLabel (returnLabel);
3051 /* now generate the end proc */
3052 ic = newiCode (ENDFUNCTION, func, NULL);
3057 /*-----------------------------------------------------------------*/
3058 /* geniCodeReturn - gen icode for 'return' statement */
3059 /*-----------------------------------------------------------------*/
3061 geniCodeReturn (operand * op)
3065 /* if the operand is present force an rvalue */
3067 op = geniCodeRValue (op, FALSE);
3069 ic = newiCode (RETURN, op, NULL);
3073 /*-----------------------------------------------------------------*/
3074 /* geniCodeIfx - generates code for extended if statement */
3075 /*-----------------------------------------------------------------*/
3077 geniCodeIfx (ast * tree,int lvl)
3080 operand *condition = ast2iCode (tree->left,lvl+1);
3083 /* if condition is null then exit */
3087 condition = geniCodeRValue (condition, FALSE);
3089 cetype = getSpec (operandType (condition));
3090 /* if the condition is a literal */
3091 if (IS_LITERAL (cetype))
3093 if (floatFromVal (condition->operand.valOperand))
3095 if (tree->trueLabel)
3096 geniCodeGoto (tree->trueLabel);
3102 if (tree->falseLabel)
3103 geniCodeGoto (tree->falseLabel);
3110 if (tree->trueLabel)
3112 ic = newiCodeCondition (condition,
3117 if (tree->falseLabel)
3118 geniCodeGoto (tree->falseLabel);
3122 ic = newiCodeCondition (condition,
3129 ast2iCode (tree->right,lvl+1);
3132 /*-----------------------------------------------------------------*/
3133 /* geniCodeJumpTable - tries to create a jump table for switch */
3134 /*-----------------------------------------------------------------*/
3136 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3138 int min = 0, max = 0, t, cnt = 0;
3145 if (!tree || !caseVals)
3148 /* the criteria for creating a jump table is */
3149 /* all integer numbers between the maximum & minimum must */
3150 /* be present , the maximum value should not exceed 255 */
3151 min = max = (int) floatFromVal (vch = caseVals);
3152 SNPRINTF (buffer, sizeof(buffer),
3154 tree->values.switchVals.swNum,
3156 addSet (&labels, newiTempLabel (buffer));
3158 /* if there is only one case value then no need */
3159 if (!(vch = vch->next))
3164 if (((t = (int) floatFromVal (vch)) - max) != 1)
3166 SNPRINTF (buffer, sizeof(buffer),
3168 tree->values.switchVals.swNum,
3170 addSet (&labels, newiTempLabel (buffer));
3176 /* if the number of case statements <= 2 then */
3177 /* it is not economical to create the jump table */
3178 /* since two compares are needed for boundary conditions */
3179 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3182 if (tree->values.switchVals.swDefault)
3184 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3188 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3192 falseLabel = newiTempLabel (buffer);
3194 /* so we can create a jumptable */
3195 /* first we rule out the boundary conditions */
3196 /* if only optimization says so */
3197 if (!optimize.noJTabBoundary)
3199 sym_link *cetype = getSpec (operandType (cond));
3200 /* no need to check the lower bound if
3201 the condition is unsigned & minimum value is zero */
3202 if (!(min == 0 && SPEC_USIGN (cetype)))
3204 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3205 ic = newiCodeCondition (boundary, falseLabel, NULL);
3209 /* now for upper bounds */
3210 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3211 ic = newiCodeCondition (boundary, falseLabel, NULL);
3215 /* if the min is not zero then we no make it zero */
3218 cond = geniCodeSubtract (cond, operandFromLit (min));
3219 setOperandType (cond, UCHARTYPE);
3222 /* now create the jumptable */
3223 ic = newiCode (JUMPTABLE, NULL, NULL);
3224 IC_JTCOND (ic) = cond;
3225 IC_JTLABELS (ic) = labels;
3230 /*-----------------------------------------------------------------*/
3231 /* geniCodeSwitch - changes a switch to a if statement */
3232 /*-----------------------------------------------------------------*/
3234 geniCodeSwitch (ast * tree,int lvl)
3237 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3238 value *caseVals = tree->values.switchVals.swVals;
3239 symbol *trueLabel, *falseLabel;
3241 /* if we can make this a jump table */
3242 if (geniCodeJumpTable (cond, caseVals, tree))
3243 goto jumpTable; /* no need for the comparison */
3245 /* for the cases defined do */
3249 operand *compare = geniCodeLogic (cond,
3250 operandFromValue (caseVals),
3253 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3254 tree->values.switchVals.swNum,
3255 (int) floatFromVal (caseVals));
3256 trueLabel = newiTempLabel (buffer);
3258 ic = newiCodeCondition (compare, trueLabel, NULL);
3260 caseVals = caseVals->next;
3265 /* if default is present then goto break else break */
3266 if (tree->values.switchVals.swDefault)
3268 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3272 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3275 falseLabel = newiTempLabel (buffer);
3276 geniCodeGoto (falseLabel);
3279 ast2iCode (tree->right,lvl+1);
3282 /*-----------------------------------------------------------------*/
3283 /* geniCodeInline - intermediate code for inline assembler */
3284 /*-----------------------------------------------------------------*/
3286 geniCodeInline (ast * tree)
3290 ic = newiCode (INLINEASM, NULL, NULL);
3291 IC_INLINE (ic) = tree->values.inlineasm;
3295 /*-----------------------------------------------------------------*/
3296 /* geniCodeArrayInit - intermediate code for array initializer */
3297 /*-----------------------------------------------------------------*/
3299 geniCodeArrayInit (ast * tree, operand *array)
3303 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3304 ic = newiCode (ARRAYINIT, array, NULL);
3305 IC_ARRAYILIST (ic) = tree->values.constlist;
3307 operand *left=newOperand(), *right=newOperand();
3308 left->type=right->type=SYMBOL;
3309 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3310 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3311 ic = newiCode (ARRAYINIT, left, right);
3316 /*-----------------------------------------------------------------*/
3317 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3318 /* particular case. Ie : assigning or dereferencing array or ptr */
3319 /*-----------------------------------------------------------------*/
3320 set * lvaluereqSet = NULL;
3321 typedef struct lvalItem
3328 /*-----------------------------------------------------------------*/
3329 /* addLvaluereq - add a flag for lvalreq for current ast level */
3330 /*-----------------------------------------------------------------*/
3331 void addLvaluereq(int lvl)
3333 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3336 addSetHead(&lvaluereqSet,lpItem);
3339 /*-----------------------------------------------------------------*/
3340 /* delLvaluereq - del a flag for lvalreq for current ast level */
3341 /*-----------------------------------------------------------------*/
3345 lpItem = getSet(&lvaluereqSet);
3346 if(lpItem) Safe_free(lpItem);
3348 /*-----------------------------------------------------------------*/
3349 /* clearLvaluereq - clear lvalreq flag */
3350 /*-----------------------------------------------------------------*/
3351 void clearLvaluereq()
3354 lpItem = peekSet(lvaluereqSet);
3355 if(lpItem) lpItem->req = 0;
3357 /*-----------------------------------------------------------------*/
3358 /* getLvaluereq - get the last lvalreq level */
3359 /*-----------------------------------------------------------------*/
3360 int getLvaluereqLvl()
3363 lpItem = peekSet(lvaluereqSet);
3364 if(lpItem) return lpItem->lvl;
3367 /*-----------------------------------------------------------------*/
3368 /* isLvaluereq - is lvalreq valid for this level ? */
3369 /*-----------------------------------------------------------------*/
3370 int isLvaluereq(int lvl)
3373 lpItem = peekSet(lvaluereqSet);
3374 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3378 /*-----------------------------------------------------------------*/
3379 /* ast2iCode - creates an icodeList from an ast */
3380 /*-----------------------------------------------------------------*/
3382 ast2iCode (ast * tree,int lvl)
3384 operand *left = NULL;
3385 operand *right = NULL;
3389 /* set the global variables for filename & line number */
3391 filename = tree->filename;
3393 lineno = tree->lineno;
3395 block = tree->block;
3397 scopeLevel = tree->level;
3399 if (tree->type == EX_VALUE)
3400 return operandFromValue (tree->opval.val);
3402 if (tree->type == EX_LINK)
3403 return operandFromLink (tree->opval.lnk);
3405 /* if we find a nullop */
3406 if (tree->type == EX_OP &&
3407 (tree->opval.op == NULLOP ||
3408 tree->opval.op == BLOCK))
3410 ast2iCode (tree->left,lvl+1);
3411 ast2iCode (tree->right,lvl+1);
3415 /* special cases for not evaluating */
3416 if (tree->opval.op != ':' &&
3417 tree->opval.op != '?' &&
3418 tree->opval.op != CALL &&
3419 tree->opval.op != IFX &&
3420 tree->opval.op != LABEL &&
3421 tree->opval.op != GOTO &&
3422 tree->opval.op != SWITCH &&
3423 tree->opval.op != FUNCTION &&
3424 tree->opval.op != INLINEASM)
3427 if (IS_ASSIGN_OP (tree->opval.op) ||
3428 IS_DEREF_OP (tree) ||
3429 (tree->opval.op == '&' && !tree->right) ||
3430 tree->opval.op == PTR_OP)
3433 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3434 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3437 left = operandFromAst (tree->left,lvl);
3439 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3440 left = geniCodeRValue (left, TRUE);
3444 left = operandFromAst (tree->left,lvl);
3446 if (tree->opval.op == INC_OP ||
3447 tree->opval.op == DEC_OP)
3450 right = operandFromAst (tree->right,lvl);
3455 right = operandFromAst (tree->right,lvl);
3459 /* now depending on the type of operand */
3460 /* this will be a biggy */
3461 switch (tree->opval.op)
3464 case '[': /* array operation */
3466 //sym_link *ltype = operandType (left);
3467 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3468 left = geniCodeRValue (left, FALSE);
3469 right = geniCodeRValue (right, TRUE);
3472 return geniCodeArray (left, right,lvl);
3474 case '.': /* structure dereference */
3475 if (IS_PTR (operandType (left)))
3476 left = geniCodeRValue (left, TRUE);
3478 left = geniCodeRValue (left, FALSE);
3480 return geniCodeStruct (left, right, tree->lvalue);
3482 case PTR_OP: /* structure pointer dereference */
3485 pType = operandType (left);
3486 left = geniCodeRValue (left, TRUE);
3488 setOClass (pType, getSpec (operandType (left)));
3491 return geniCodeStruct (left, right, tree->lvalue);
3493 case INC_OP: /* increment operator */
3495 return geniCodePostInc (left);
3497 return geniCodePreInc (right);
3499 case DEC_OP: /* decrement operator */
3501 return geniCodePostDec (left);
3503 return geniCodePreDec (right);
3505 case '&': /* bitwise and or address of operator */
3507 { /* this is a bitwise operator */
3508 left = geniCodeRValue (left, FALSE);
3509 right = geniCodeRValue (right, FALSE);
3510 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3513 return geniCodeAddressOf (left);
3515 case '|': /* bitwise or & xor */
3517 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3518 geniCodeRValue (right, FALSE),
3523 return geniCodeDivision (geniCodeRValue (left, FALSE),
3524 geniCodeRValue (right, FALSE));
3527 return geniCodeModulus (geniCodeRValue (left, FALSE),
3528 geniCodeRValue (right, FALSE));
3531 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3532 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3534 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3538 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3539 geniCodeRValue (right, FALSE));
3541 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3545 return geniCodeAdd (geniCodeRValue (left, FALSE),
3546 geniCodeRValue (right, FALSE),lvl);
3548 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3551 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3552 geniCodeRValue (right, FALSE));
3555 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3556 geniCodeRValue (right, FALSE));
3558 #if 0 // this indeed needs a second thought
3562 // let's keep this simple: get the rvalue we need
3563 op=geniCodeRValue (right, FALSE);
3564 // now cast it to whatever we want
3565 op=geniCodeCast (operandType(left), op, FALSE);
3566 // if this is going to be used as an lvalue, make it so
3572 #else // bug #604575, is it a bug ????
3573 return geniCodeCast (operandType (left),
3574 geniCodeRValue (right, FALSE), FALSE);
3581 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3585 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3586 setOperandType (op, UCHARTYPE);
3597 return geniCodeLogic (geniCodeRValue (left, FALSE),
3598 geniCodeRValue (right, FALSE),
3601 return geniCodeConditional (tree,lvl);
3604 return operandFromLit (getSize (tree->right->ftype));
3608 sym_link *rtype = operandType (right);
3609 sym_link *ltype = operandType (left);
3610 if (IS_PTR (rtype) && IS_ITEMP (right)
3611 && right->isaddr && compareType (rtype->next, ltype) == 1)
3612 right = geniCodeRValue (right, TRUE);
3614 right = geniCodeRValue (right, FALSE);
3616 geniCodeAssign (left, right, 0);
3621 geniCodeAssign (left,
3622 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3624 geniCodeRValue (right, FALSE),FALSE), 0);
3628 geniCodeAssign (left,
3629 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3631 geniCodeRValue (right, FALSE)), 0);
3634 geniCodeAssign (left,
3635 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3637 geniCodeRValue (right, FALSE)), 0);
3640 sym_link *rtype = operandType (right);
3641 sym_link *ltype = operandType (left);
3642 if (IS_PTR (rtype) && IS_ITEMP (right)
3643 && right->isaddr && compareType (rtype->next, ltype) == 1)
3644 right = geniCodeRValue (right, TRUE);
3646 right = geniCodeRValue (right, FALSE);
3649 return geniCodeAssign (left,
3650 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3656 sym_link *rtype = operandType (right);
3657 sym_link *ltype = operandType (left);
3658 if (IS_PTR (rtype) && IS_ITEMP (right)
3659 && right->isaddr && compareType (rtype->next, ltype) == 1)
3661 right = geniCodeRValue (right, TRUE);
3665 right = geniCodeRValue (right, FALSE);
3668 geniCodeAssign (left,
3669 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3675 geniCodeAssign (left,
3676 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3678 geniCodeRValue (right, FALSE)), 0);
3681 geniCodeAssign (left,
3682 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3684 geniCodeRValue (right, FALSE)), 0);
3687 geniCodeAssign (left,
3688 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3690 geniCodeRValue (right, FALSE),
3692 operandType (left)), 0);
3695 geniCodeAssign (left,
3696 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3698 geniCodeRValue (right, FALSE),
3700 operandType (left)), 0);
3703 geniCodeAssign (left,
3704 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3706 geniCodeRValue (right, FALSE),
3708 operandType (left)), 0);
3710 return geniCodeRValue (right, FALSE);
3713 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3716 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3717 return ast2iCode (tree->right,lvl+1);
3720 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3721 return ast2iCode (tree->right,lvl+1);
3724 geniCodeFunctionBody (tree,lvl);
3728 geniCodeReturn (right);
3732 geniCodeIfx (tree,lvl);
3736 geniCodeSwitch (tree,lvl);
3740 geniCodeInline (tree);
3744 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3751 /*-----------------------------------------------------------------*/
3752 /* reverseICChain - gets from the list and creates a linkedlist */
3753 /*-----------------------------------------------------------------*/
3760 while ((loop = getSet (&iCodeChain)))
3772 /*-----------------------------------------------------------------*/
3773 /* iCodeFromAst - given an ast will convert it to iCode */
3774 /*-----------------------------------------------------------------*/
3776 iCodeFromAst (ast * tree)
3778 returnLabel = newiTempLabel ("_return");
3779 entryLabel = newiTempLabel ("_entry");
3781 return reverseiCChain ();
3784 static const char *opTypeToStr(OPTYPE op)
3788 case SYMBOL: return "symbol";
3789 case VALUE: return "value";
3790 case TYPE: return "type";
3792 return "undefined type";
3796 operand *validateOpType(operand *op,
3803 if (op && op->type == type)
3808 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
3809 " expected %s, got %s\n",
3810 macro, args, file, line,
3811 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
3813 return op; // never reached, makes compiler happy.