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;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeAssign (operand *, operand *, int, int);
49 static operand *geniCodeArray (operand *, operand *,int);
50 static operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
54 void setOClass (sym_link * ptr, sym_link * spec);
55 static operand *geniCodeCast (sym_link *, operand *, bool);
57 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
58 /* forward definition of ic print functions */
59 PRINTFUNC (picGetValueAtAddr);
60 PRINTFUNC (picSetValueAtAddr);
61 PRINTFUNC (picAddrOf);
62 PRINTFUNC (picGeneric);
63 PRINTFUNC (picGenericOne);
65 PRINTFUNC (picAssign);
69 PRINTFUNC (picJumpTable);
70 PRINTFUNC (picInline);
71 PRINTFUNC (picReceive);
72 PRINTFUNC (picDummyRead);
73 PRINTFUNC (picCritical);
74 PRINTFUNC (picEndCritical);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
121 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
122 {CRITICAL, "critical_start", picCritical, NULL},
123 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
124 {SWAP, "swap", picGenericOne, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%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}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
281 fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
285 fprintf (file, "[lr%d:%d so:%d]",
286 OP_LIVEFROM (op), OP_LIVETO (op),
287 OP_SYMBOL (op)->stack
294 printTypeChain (operandType (op), file);
295 if (SPIL_LOC (op) && IS_ITEMP (op))
296 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
302 /* if assigned to registers */
303 if (OP_SYMBOL (op)->nRegs)
305 if (OP_SYMBOL (op)->isspilt)
307 if (!OP_SYMBOL (op)->remat)
308 if (OP_SYMBOL (op)->usl.spillLoc)
309 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
310 OP_SYMBOL (op)->usl.spillLoc->rname :
311 OP_SYMBOL (op)->usl.spillLoc->name));
313 fprintf (file, "[err]");
315 fprintf (file, "[remat]");
321 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
322 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
331 printTypeChain (op->operand.typeOperand, file);
337 fprintf (file, "\n");
342 /*-----------------------------------------------------------------*/
343 /* print functions */
344 /*-----------------------------------------------------------------*/
345 PRINTFUNC (picGetValueAtAddr)
348 printOperand (IC_RESULT (ic), of);
351 printOperand (IC_LEFT (ic), of);
357 PRINTFUNC (picSetValueAtAddr)
361 printOperand (IC_LEFT (ic), of);
362 fprintf (of, "] = ");
363 printOperand (IC_RIGHT (ic), of);
367 PRINTFUNC (picAddrOf)
370 printOperand (IC_RESULT (ic), of);
371 if (IS_ITEMP (IC_LEFT (ic)))
374 fprintf (of, " = &[");
375 printOperand (IC_LEFT (ic), of);
378 if (IS_ITEMP (IC_LEFT (ic)))
379 fprintf (of, " offsetAdd ");
382 printOperand (IC_RIGHT (ic), of);
384 if (IS_ITEMP (IC_LEFT (ic)))
390 PRINTFUNC (picJumpTable)
395 fprintf (of, "%s\t", s);
396 printOperand (IC_JTCOND (ic), of);
398 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
399 sym = setNextItem (IC_JTLABELS (ic)))
400 fprintf (of, "\t\t\t%s\n", sym->name);
403 PRINTFUNC (picGeneric)
406 printOperand (IC_RESULT (ic), of);
408 printOperand (IC_LEFT (ic), of);
409 fprintf (of, " %s ", s);
410 printOperand (IC_RIGHT (ic), of);
414 PRINTFUNC (picGenericOne)
419 printOperand (IC_RESULT (ic), of);
425 fprintf (of, "%s ", s);
426 printOperand (IC_LEFT (ic), of);
429 if (!IC_RESULT (ic) && !IC_LEFT (ic))
432 if (ic->op == SEND || ic->op == RECEIVE) {
433 fprintf(of,"{argreg = %d}",ic->argreg);
435 if (ic->op == IPUSH) {
436 fprintf(of,"{parmPush = %d}",ic->parmPush);
444 printOperand (IC_RESULT (ic), of);
446 printOperand (IC_LEFT (ic), of);
447 printOperand (IC_RIGHT (ic), of);
452 PRINTFUNC (picAssign)
456 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
459 printOperand (IC_RESULT (ic), of);
461 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
464 fprintf (of, " %s ", s);
465 printOperand (IC_RIGHT (ic), of);
472 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
478 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
485 printOperand (IC_COND (ic), of);
488 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
491 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
493 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
497 PRINTFUNC (picInline)
499 fprintf (of, "%s", IC_INLINE (ic));
502 PRINTFUNC (picReceive)
504 printOperand (IC_RESULT (ic), of);
505 fprintf (of, " = %s ", s);
506 printOperand (IC_LEFT (ic), of);
510 PRINTFUNC (picDummyRead)
513 fprintf (of, "%s ", s);
514 printOperand (IC_RIGHT (ic), of);
518 PRINTFUNC (picCritical)
522 printOperand (IC_RESULT (ic), of);
524 fprintf (of, "(stack)");
525 fprintf (of, " = %s ", s);
529 PRINTFUNC (picEndCritical)
532 fprintf (of, "%s = ", s);
534 printOperand (IC_RIGHT (ic), of);
536 fprintf (of, "(stack)");
540 /*-----------------------------------------------------------------*/
541 /* piCode - prints one iCode */
542 /*-----------------------------------------------------------------*/
544 piCode (void *item, FILE * of)
552 icTab = getTableEntry (ic->op);
553 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
554 ic->filename, ic->lineno,
555 ic->seq, ic->key, ic->depth, ic->supportRtn);
556 icTab->iCodePrint (of, ic, icTab->printName);
562 printiCChain(ic,stdout);
564 /*-----------------------------------------------------------------*/
565 /* printiCChain - prints intermediate code for humans */
566 /*-----------------------------------------------------------------*/
568 printiCChain (iCode * icChain, FILE * of)
575 for (loop = icChain; loop; loop = loop->next)
577 if ((icTab = getTableEntry (loop->op)))
579 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
580 loop->filename, loop->lineno,
581 loop->seq, loop->key, loop->depth, loop->supportRtn);
583 icTab->iCodePrint (of, loop, icTab->printName);
589 /*-----------------------------------------------------------------*/
590 /* newOperand - allocate, init & return a new iCode */
591 /*-----------------------------------------------------------------*/
597 op = Safe_alloc ( sizeof (operand));
603 /*-----------------------------------------------------------------*/
604 /* newiCode - create and return a new iCode entry initialised */
605 /*-----------------------------------------------------------------*/
607 newiCode (int op, operand * left, operand * right)
611 ic = Safe_alloc ( sizeof (iCode));
613 ic->seqPoint = seqPoint;
615 ic->filename = filename;
617 ic->level = scopeLevel;
619 ic->key = iCodeKey++;
621 IC_RIGHT (ic) = right;
626 /*-----------------------------------------------------------------*/
627 /* newiCode for conditional statements */
628 /*-----------------------------------------------------------------*/
630 newiCodeCondition (operand * condition,
636 if (IS_VOID(operandType(condition))) {
637 werror(E_VOID_VALUE_USED);
640 ic = newiCode (IFX, NULL, NULL);
641 IC_COND (ic) = condition;
642 IC_TRUE (ic) = trueLabel;
643 IC_FALSE (ic) = falseLabel;
647 /*-----------------------------------------------------------------*/
648 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
649 /*-----------------------------------------------------------------*/
651 newiCodeLabelGoto (int op, symbol * label)
655 ic = newiCode (op, NULL, NULL);
659 IC_RIGHT (ic) = NULL;
660 IC_RESULT (ic) = NULL;
664 /*-----------------------------------------------------------------*/
665 /* newiTemp - allocate & return a newItemp Variable */
666 /*-----------------------------------------------------------------*/
674 SNPRINTF (buffer, sizeof(buffer), "%s", s);
678 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
681 itmp = newSymbol (buffer, 1);
682 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
688 /*-----------------------------------------------------------------*/
689 /* newiTempLabel - creates a temp variable label */
690 /*-----------------------------------------------------------------*/
692 newiTempLabel (char *s)
696 /* check if this already exists */
697 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
702 itmplbl = newSymbol (s, 1);
706 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
707 itmplbl = newSymbol (buffer, 1);
712 itmplbl->key = labelKey++;
713 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
717 /*-----------------------------------------------------------------*/
718 /* newiTempPreheaderLabel - creates a new preheader label */
719 /*-----------------------------------------------------------------*/
721 newiTempPreheaderLabel ()
725 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
726 itmplbl = newSymbol (buffer, 1);
730 itmplbl->key = labelKey++;
731 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
736 /*-----------------------------------------------------------------*/
737 /* initiCode - initialises some iCode related stuff */
738 /*-----------------------------------------------------------------*/
745 /*-----------------------------------------------------------------*/
746 /* copyiCode - make a copy of the iCode given */
747 /*-----------------------------------------------------------------*/
749 copyiCode (iCode * ic)
751 iCode *nic = newiCode (ic->op, NULL, NULL);
753 nic->lineno = ic->lineno;
754 nic->filename = ic->filename;
755 nic->block = ic->block;
756 nic->level = ic->level;
757 nic->parmBytes = ic->parmBytes;
759 /* deal with the special cases first */
763 IC_COND (nic) = operandFromOperand (IC_COND (ic));
764 IC_TRUE (nic) = IC_TRUE (ic);
765 IC_FALSE (nic) = IC_FALSE (ic);
769 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
770 IC_JTLABELS (nic) = IC_JTLABELS (ic);
775 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
776 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
780 IC_INLINE (nic) = IC_INLINE (ic);
784 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
788 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
789 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
790 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
796 /*-----------------------------------------------------------------*/
797 /* getTableEntry - gets the table entry for the given operator */
798 /*-----------------------------------------------------------------*/
800 getTableEntry (int oper)
804 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
805 if (oper == codeTable[i].icode)
806 return &codeTable[i];
811 /*-----------------------------------------------------------------*/
812 /* newiTempOperand - new intermediate temp operand */
813 /*-----------------------------------------------------------------*/
815 newiTempOperand (sym_link * type, char throwType)
818 operand *op = newOperand ();
822 itmp = newiTemp (NULL);
824 etype = getSpec (type);
826 if (IS_LITERAL (etype))
829 /* copy the type information */
831 itmp->etype = getSpec (itmp->type = (throwType ? type :
832 copyLinkChain (type)));
833 if (IS_LITERAL (itmp->etype))
835 SPEC_SCLS (itmp->etype) = S_REGISTER;
836 SPEC_OCLS (itmp->etype) = reg;
839 op->operand.symOperand = itmp;
840 op->key = itmp->key = ++operandKey;
844 /*-----------------------------------------------------------------*/
845 /* operandType - returns the type chain for an operand */
846 /*-----------------------------------------------------------------*/
848 operandType (operand * op)
850 /* depending on type of operand */
855 return op->operand.valOperand->type;
858 return op->operand.symOperand->type;
861 return op->operand.typeOperand;
863 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
864 " operand type not known ");
865 assert (0); /* should never come here */
866 /* Just to keep the compiler happy */
867 return (sym_link *) 0;
871 /*-----------------------------------------------------------------*/
872 /* isParamterToCall - will return 1 if op is a parameter to args */
873 /*-----------------------------------------------------------------*/
875 isParameterToCall (value * args, operand * op)
879 wassert (IS_SYMOP(op));
884 isSymbolEqual (op->operand.symOperand, tval->sym))
891 /*-----------------------------------------------------------------*/
892 /* isOperandGlobal - return 1 if operand is a global variable */
893 /*-----------------------------------------------------------------*/
895 isOperandGlobal (operand * op)
904 (op->operand.symOperand->level == 0 ||
905 IS_STATIC (op->operand.symOperand->etype) ||
906 IS_EXTERN (op->operand.symOperand->etype))
913 /*-----------------------------------------------------------------*/
914 /* isOperandVolatile - return 1 if the operand is volatile */
915 /*-----------------------------------------------------------------*/
917 isOperandVolatile (operand * op, bool chkTemp)
922 if (IS_ITEMP (op) && !chkTemp)
925 opetype = getSpec (optype = operandType (op));
927 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
930 if (IS_VOLATILE (opetype))
935 /*-----------------------------------------------------------------*/
936 /* isOperandLiteral - returns 1 if an operand contains a literal */
937 /*-----------------------------------------------------------------*/
939 isOperandLiteral (operand * op)
946 opetype = getSpec (operandType (op));
948 if (IS_LITERAL (opetype))
954 /*-----------------------------------------------------------------*/
955 /* isOperandInFarSpace - will return true if operand is in farSpace */
956 /*-----------------------------------------------------------------*/
958 isOperandInFarSpace (operand * op)
968 if (!IS_TRUE_SYMOP (op))
971 etype = SPIL_LOC (op)->etype;
977 etype = getSpec (operandType (op));
979 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
982 /*------------------------------------------------------------------*/
983 /* isOperandInDirSpace - will return true if operand is in dirSpace */
984 /*------------------------------------------------------------------*/
986 isOperandInDirSpace (operand * op)
996 if (!IS_TRUE_SYMOP (op))
999 etype = SPIL_LOC (op)->etype;
1005 etype = getSpec (operandType (op));
1007 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1010 /*--------------------------------------------------------------------*/
1011 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
1012 /*--------------------------------------------------------------------*/
1014 isOperandInCodeSpace (operand * op)
1024 etype = getSpec (operandType (op));
1026 if (!IS_TRUE_SYMOP (op))
1029 etype = SPIL_LOC (op)->etype;
1035 etype = getSpec (operandType (op));
1037 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1040 /*-----------------------------------------------------------------*/
1041 /* isOperandOnStack - will return true if operand is on stack */
1042 /*-----------------------------------------------------------------*/
1044 isOperandOnStack (operand * op)
1054 etype = getSpec (operandType (op));
1055 if (IN_STACK (etype) ||
1056 OP_SYMBOL(op)->onStack ||
1057 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1063 /*-----------------------------------------------------------------*/
1064 /* isOclsExpensive - will return true if accesses to an output */
1065 /* storage class are expensive */
1066 /*-----------------------------------------------------------------*/
1068 isOclsExpensive (struct memmap *oclass)
1070 if (port->oclsExpense)
1071 return port->oclsExpense (oclass) > 0;
1073 /* In the absence of port specific guidance, assume only */
1074 /* farspace is expensive. */
1075 return IN_FARSPACE (oclass);
1078 /*-----------------------------------------------------------------*/
1079 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1080 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1081 /*-----------------------------------------------------------------*/
1083 isiCodeInFunctionCall (iCode * ic)
1087 /* Find the next CALL/PCALL */
1090 if (lic->op == CALL || lic->op == PCALL)
1098 /* A function call was found. Scan backwards and see if an */
1099 /* IPUSH or SEND is encountered */
1102 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1104 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1112 /*-----------------------------------------------------------------*/
1113 /* operandLitValue - literal value of an operand */
1114 /*-----------------------------------------------------------------*/
1116 operandLitValue (operand * op)
1118 assert (isOperandLiteral (op));
1120 return floatFromVal (op->operand.valOperand);
1123 /*-----------------------------------------------------------------*/
1124 /* getBuiltInParms - returns parameters to a builtin functions */
1125 /*-----------------------------------------------------------------*/
1126 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1131 /* builtin functions uses only SEND for parameters */
1132 while (ic->op != CALL) {
1133 assert(ic->op == SEND && ic->builtinSEND);
1134 ic->generated = 1; /* mark the icode as generated */
1135 parms[*pcount] = IC_LEFT(ic);
1141 /* make sure this is a builtin function call */
1142 assert(IS_SYMOP(IC_LEFT(ic)));
1143 ftype = operandType(IC_LEFT(ic));
1144 assert(IFFUNC_ISBUILTIN(ftype));
1148 /*-----------------------------------------------------------------*/
1149 /* operandOperation - performs operations on operands */
1150 /*-----------------------------------------------------------------*/
1152 operandOperation (operand * left, operand * right,
1153 int op, sym_link * type)
1155 sym_link *let , *ret=NULL;
1156 operand *retval = (operand *) 0;
1158 assert (isOperandLiteral (left));
1159 let = getSpec(operandType(left));
1161 assert (isOperandLiteral (right));
1162 ret = getSpec(operandType(right));
1168 retval = operandFromValue (valCastLiteral (type,
1169 operandLitValue (left) +
1170 operandLitValue (right)));
1173 retval = operandFromValue (valCastLiteral (type,
1174 operandLitValue (left) -
1175 operandLitValue (right)));
1179 retval = operandFromValue (valCastLiteral (type,
1180 operandLitValue (left) *
1181 operandLitValue (right)));
1182 This could be all we've to do, but with gcc we've to take care about
1183 overflows. Two examples:
1184 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1185 significant bits are lost (52 in fraction, 63 bits would be
1186 necessary to keep full precision).
1187 If the resulting double value is greater than ULONG_MAX (resp.
1188 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1191 /* if it is not a specifier then we can assume that */
1192 /* it will be an unsigned long */
1193 if (IS_INT (type) ||
1196 /* long is handled here, because it can overflow with double */
1197 if (IS_LONG (type) ||
1199 /* signed and unsigned mul are the same, as long as the precision
1200 of the result isn't bigger than the precision of the operands. */
1201 retval = operandFromValue (valCastLiteral (type,
1202 (TYPE_UDWORD) operandLitValue (left) *
1203 (TYPE_UDWORD) operandLitValue (right)));
1204 else if (IS_UNSIGNED (type)) /* unsigned int */
1206 /* unsigned int is handled here in order to detect overflow */
1207 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1208 (TYPE_UWORD) operandLitValue (right);
1210 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1211 if (ul != (TYPE_UWORD) ul)
1214 else /* signed int */
1216 /* signed int is handled here in order to detect overflow */
1217 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1218 (TYPE_WORD) operandLitValue (right);
1220 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1221 if (l != (TYPE_WORD) l)
1226 /* all others go here: */
1227 retval = operandFromValue (valCastLiteral (type,
1228 operandLitValue (left) *
1229 operandLitValue (right)));
1232 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1234 werror (E_DIVIDE_BY_ZERO);
1240 if (IS_UNSIGNED (type))
1242 SPEC_USIGN (let) = 1;
1243 SPEC_USIGN (ret) = 1;
1244 retval = operandFromValue (valCastLiteral (type,
1245 (TYPE_UDWORD) operandLitValue (left) /
1246 (TYPE_UDWORD) operandLitValue (right)));
1250 retval = operandFromValue (valCastLiteral (type,
1251 operandLitValue (left) /
1252 operandLitValue (right)));
1257 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1259 werror (E_DIVIDE_BY_ZERO);
1264 if (IS_UNSIGNED (type))
1265 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1266 (TYPE_UDWORD) operandLitValue (right));
1268 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1269 (TYPE_DWORD) operandLitValue (right));
1273 /* The number of left shifts is always unsigned. Signed doesn't make
1274 sense here. Shifting by a negative number is impossible. */
1275 retval = operandFromValue (valCastLiteral (type,
1276 ((TYPE_UDWORD) operandLitValue (left) <<
1277 (TYPE_UDWORD) operandLitValue (right))));
1280 /* The number of right shifts is always unsigned. Signed doesn't make
1281 sense here. Shifting by a negative number is impossible. */
1282 if (IS_UNSIGNED(let))
1283 /* unsigned: logic shift right */
1284 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1285 (TYPE_UDWORD) operandLitValue (right));
1287 /* signed: arithmetic shift right */
1288 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1289 (TYPE_UDWORD) operandLitValue (right));
1292 if (IS_FLOAT (let) ||
1295 retval = operandFromLit (operandLitValue (left) ==
1296 operandLitValue (right));
1300 /* this op doesn't care about signedness */
1303 l = (TYPE_UDWORD) operandLitValue (left);
1304 r = (TYPE_UDWORD) operandLitValue (right);
1305 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1306 neccessary to strip them to 16 bit.
1307 Literals are reduced to their cheapest type, therefore left and
1308 right might have different types. It's neccessary to find a
1309 common type: int (used for char too) or long */
1310 if (!IS_LONG (let) &&
1316 retval = operandFromLit (l == r);
1320 retval = operandFromLit (operandLitValue (left) <
1321 operandLitValue (right));
1324 retval = operandFromLit (operandLitValue (left) <=
1325 operandLitValue (right));
1328 retval = operandFromLit (operandLitValue (left) !=
1329 operandLitValue (right));
1332 retval = operandFromLit (operandLitValue (left) >
1333 operandLitValue (right));
1336 retval = operandFromLit (operandLitValue (left) >=
1337 operandLitValue (right));
1340 retval = operandFromValue (valCastLiteral (type,
1341 (TYPE_UDWORD)operandLitValue(left) &
1342 (TYPE_UDWORD)operandLitValue(right)));
1345 retval = operandFromValue (valCastLiteral (type,
1346 (TYPE_UDWORD)operandLitValue(left) |
1347 (TYPE_UDWORD)operandLitValue(right)));
1350 retval = operandFromValue (valCastLiteral (type,
1351 (TYPE_UDWORD)operandLitValue(left) ^
1352 (TYPE_UDWORD)operandLitValue(right)));
1355 retval = operandFromLit (operandLitValue (left) &&
1356 operandLitValue (right));
1359 retval = operandFromLit (operandLitValue (left) ||
1360 operandLitValue (right));
1364 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1366 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1372 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1374 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1380 retval = operandFromValue (valCastLiteral (type,
1381 -1 * operandLitValue (left)));
1385 retval = operandFromValue (valCastLiteral (type,
1387 operandLitValue (left))));
1391 retval = operandFromLit (!operandLitValue (left));
1395 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1396 " operandOperation invalid operator ");
1404 /*-----------------------------------------------------------------*/
1405 /* isOperandEqual - compares two operand & return 1 if they r = */
1406 /*-----------------------------------------------------------------*/
1408 isOperandEqual (operand * left, operand * right)
1410 /* if the pointers are equal then they are equal */
1414 /* if either of them null then false */
1415 if (!left || !right)
1418 if (left->type != right->type)
1421 if (IS_SYMOP (left) && IS_SYMOP (right))
1422 return left->key == right->key;
1424 /* if types are the same */
1428 return isSymbolEqual (left->operand.symOperand,
1429 right->operand.symOperand);
1431 return (floatFromVal (left->operand.valOperand) ==
1432 floatFromVal (right->operand.valOperand));
1434 if (compareType (left->operand.typeOperand,
1435 right->operand.typeOperand) == 1)
1442 /*-------------------------------------------------------------------*/
1443 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1444 /*-------------------------------------------------------------------*/
1446 isiCodeEqual (iCode * left, iCode * right)
1448 /* if the same pointer */
1452 /* if either of them null */
1453 if (!left || !right)
1456 /* if operand are the same */
1457 if (left->op == right->op)
1460 /* compare all the elements depending on type */
1461 if (left->op != IFX)
1463 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1465 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1471 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1473 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1475 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1484 /*-----------------------------------------------------------------*/
1485 /* newiTempFromOp - create a temp Operand with same attributes */
1486 /*-----------------------------------------------------------------*/
1488 newiTempFromOp (operand * op)
1498 nop = newiTempOperand (operandType (op), TRUE);
1499 nop->isaddr = op->isaddr;
1500 nop->isvolatile = op->isvolatile;
1501 nop->isGlobal = op->isGlobal;
1502 nop->isLiteral = op->isLiteral;
1503 nop->usesDefs = op->usesDefs;
1504 nop->isParm = op->isParm;
1508 /*-----------------------------------------------------------------*/
1509 /* operand from operand - creates an operand holder for the type */
1510 /*-----------------------------------------------------------------*/
1512 operandFromOperand (operand * op)
1518 nop = newOperand ();
1519 nop->type = op->type;
1520 nop->isaddr = op->isaddr;
1522 nop->isvolatile = op->isvolatile;
1523 nop->isGlobal = op->isGlobal;
1524 nop->isLiteral = op->isLiteral;
1525 nop->usesDefs = op->usesDefs;
1526 nop->isParm = op->isParm;
1531 nop->operand.symOperand = op->operand.symOperand;
1534 nop->operand.valOperand = op->operand.valOperand;
1537 nop->operand.typeOperand = op->operand.typeOperand;
1544 /*-----------------------------------------------------------------*/
1545 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1546 /*-----------------------------------------------------------------*/
1548 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1550 operand *nop = operandFromOperand (op);
1552 if (nop->type == SYMBOL)
1554 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1555 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1561 /*-----------------------------------------------------------------*/
1562 /* operandFromSymbol - creates an operand from a symbol */
1563 /*-----------------------------------------------------------------*/
1565 operandFromSymbol (symbol * sym)
1570 /* if the symbol's type is a literal */
1571 /* then it is an enumerator type */
1572 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1573 return operandFromValue (valFromType (sym->etype));
1576 sym->key = ++operandKey;
1578 /* if this an implicit variable, means struct/union */
1579 /* member so just return it */
1580 if (sym->implicit || IS_FUNC (sym->type))
1584 op->operand.symOperand = sym;
1586 op->isvolatile = isOperandVolatile (op, TRUE);
1587 op->isGlobal = isOperandGlobal (op);
1591 /* under the following conditions create a
1592 register equivalent for a local symbol */
1593 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1594 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1596 (!(options.model == MODEL_FLAT24)) ) &&
1597 options.stackAuto == 0)
1600 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1601 !IS_FUNC (sym->type) && /* not a function */
1602 !sym->_isparm && /* not a parameter */
1603 IS_AUTO (sym) && /* is a local auto variable */
1604 !sym->addrtaken && /* whose address has not been taken */
1605 !sym->reqv && /* does not already have a reg equivalence */
1606 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1607 !sym->islbl && /* not a label */
1608 ok && /* farspace check */
1609 !IS_BITVAR (sym->etype) /* not a bit variable */
1613 /* we will use it after all optimizations
1614 and before liveRange calculation */
1615 sym->reqv = newiTempOperand (sym->type, 0);
1616 sym->reqv->key = sym->key;
1617 OP_SYMBOL (sym->reqv)->prereqv = sym;
1618 OP_SYMBOL (sym->reqv)->key = sym->key;
1619 OP_SYMBOL (sym->reqv)->isreqv = 1;
1620 OP_SYMBOL (sym->reqv)->islocal = 1;
1621 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1622 SPIL_LOC (sym->reqv) = sym;
1625 if (!IS_AGGREGATE (sym->type))
1629 op->operand.symOperand = sym;
1632 op->isvolatile = isOperandVolatile (op, TRUE);
1633 op->isGlobal = isOperandGlobal (op);
1634 op->isPtr = IS_PTR (operandType (op));
1635 op->isParm = sym->_isparm;
1640 /* itemp = &[_symbol] */
1642 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1643 IC_LEFT (ic)->type = SYMBOL;
1644 IC_LEFT (ic)->operand.symOperand = sym;
1645 IC_LEFT (ic)->key = sym->key;
1646 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1647 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1648 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1651 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1652 if (IS_ARRAY (sym->type))
1654 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1655 IC_RESULT (ic)->isaddr = 0;
1658 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1662 return IC_RESULT (ic);
1665 /*-----------------------------------------------------------------*/
1666 /* operandFromValue - creates an operand from value */
1667 /*-----------------------------------------------------------------*/
1669 operandFromValue (value * val)
1673 /* if this is a symbol then do the symbol thing */
1675 return operandFromSymbol (val->sym);
1677 /* this is not a symbol */
1680 op->operand.valOperand = val;
1681 op->isLiteral = isOperandLiteral (op);
1685 /*-----------------------------------------------------------------*/
1686 /* operandFromLink - operand from typeChain */
1687 /*-----------------------------------------------------------------*/
1689 operandFromLink (sym_link * type)
1693 /* operand from sym_link */
1699 op->operand.typeOperand = copyLinkChain (type);
1703 /*-----------------------------------------------------------------*/
1704 /* operandFromLit - makes an operand from a literal value */
1705 /*-----------------------------------------------------------------*/
1707 operandFromLit (double i)
1709 return operandFromValue (valueFromLit (i));
1712 /*-----------------------------------------------------------------*/
1713 /* operandFromAst - creates an operand from an ast */
1714 /*-----------------------------------------------------------------*/
1716 operandFromAst (ast * tree,int lvl)
1722 /* depending on type do */
1726 return ast2iCode (tree,lvl+1);
1730 return operandFromValue (tree->opval.val);
1734 return operandFromLink (tree->opval.lnk);
1741 /* Just to keep the compiler happy */
1742 return (operand *) 0;
1745 /*-----------------------------------------------------------------*/
1746 /* setOperandType - sets the operand's type to the given type */
1747 /*-----------------------------------------------------------------*/
1749 setOperandType (operand * op, sym_link * type)
1751 /* depending on the type of operand */
1756 op->operand.valOperand->etype =
1757 getSpec (op->operand.valOperand->type =
1758 copyLinkChain (type));
1762 if (op->operand.symOperand->isitmp)
1763 op->operand.symOperand->etype =
1764 getSpec (op->operand.symOperand->type =
1765 copyLinkChain (type));
1767 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1768 "attempt to modify type of source");
1772 op->operand.typeOperand = copyLinkChain (type);
1778 /*-----------------------------------------------------------------*/
1779 /* Get size in byte of ptr need to access an array */
1780 /*-----------------------------------------------------------------*/
1782 getArraySizePtr (operand * op)
1784 sym_link *ltype = operandType(op);
1788 int size = getSize(ltype);
1789 return(IS_GENPTR(ltype)?(size-1):size);
1794 sym_link *letype = getSpec(ltype);
1795 switch (PTR_TYPE (SPEC_OCLS (letype)))
1807 return (GPTRSIZE-1);
1816 /*-----------------------------------------------------------------*/
1817 /* perform "usual unary conversions" */
1818 /*-----------------------------------------------------------------*/
1821 usualUnaryConversions (operand * op)
1823 if (IS_INTEGRAL (operandType (op)))
1825 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1828 return geniCodeCast (INTTYPE, op, TRUE);
1835 /*-----------------------------------------------------------------*/
1836 /* perform "usual binary conversions" */
1837 /*-----------------------------------------------------------------*/
1840 usualBinaryConversions (operand ** op1, operand ** op2,
1841 RESULT_TYPE resultType, int op)
1844 sym_link *rtype = operandType (*op2);
1845 sym_link *ltype = operandType (*op1);
1847 ctype = computeType (ltype, rtype, resultType, op);
1854 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1856 /* one byte operations: keep signedness for code generator */
1864 *op1 = geniCodeCast (ctype, *op1, TRUE);
1865 *op2 = geniCodeCast (ctype, *op2, TRUE);
1870 /*-----------------------------------------------------------------*/
1871 /* geniCodeValueAtAddress - generate intermeditate code for value */
1873 /*-----------------------------------------------------------------*/
1875 geniCodeRValue (operand * op, bool force)
1878 sym_link *type = operandType (op);
1879 sym_link *etype = getSpec (type);
1881 /* if this is an array & already */
1882 /* an address then return this */
1883 if (IS_AGGREGATE (type) ||
1884 (IS_PTR (type) && !force && !op->isaddr))
1885 return operandFromOperand (op);
1887 /* if this is not an address then must be */
1888 /* rvalue already so return this one */
1892 /* if this is not a temp symbol then */
1893 if (!IS_ITEMP (op) &&
1895 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1897 op = operandFromOperand (op);
1902 if (IS_SPEC (type) &&
1903 IS_TRUE_SYMOP (op) &&
1904 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1905 (options.model == MODEL_FLAT24) ))
1907 op = operandFromOperand (op);
1912 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1913 if (IS_PTR (type) && op->isaddr && force)
1916 type = copyLinkChain (type);
1918 IC_RESULT (ic) = newiTempOperand (type, 1);
1919 IC_RESULT (ic)->isaddr = 0;
1921 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1925 return IC_RESULT (ic);
1928 /*-----------------------------------------------------------------*/
1929 /* geniCodeCast - changes the value from one type to another */
1930 /*-----------------------------------------------------------------*/
1932 geniCodeCast (sym_link * type, operand * op, bool implicit)
1936 sym_link *opetype = getSpec (optype = operandType (op));
1940 /* one of them has size zero then error */
1941 if (IS_VOID (optype))
1943 werror (E_CAST_ZERO);
1947 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1949 geniCodeArray2Ptr (op);
1953 /* if the operand is already the desired type then do nothing */
1954 if (compareType (type, optype) == 1)
1957 /* if this is a literal then just change the type & return */
1958 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1960 return operandFromValue (valCastLiteral (type,
1961 operandLitValue (op)));
1964 /* if casting to/from pointers, do some checking */
1965 if (IS_PTR(type)) { // to a pointer
1966 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1967 if (IS_INTEGRAL(optype)) {
1968 // maybe this is NULL, than it's ok.
1969 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1970 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1971 // no way to set the storage
1972 if (IS_LITERAL(optype)) {
1973 werror(E_LITERAL_GENERIC);
1976 werror(E_NONPTR2_GENPTR);
1979 } else if (implicit) {
1980 werror(W_INTEGRAL2PTR_NOCAST);
1985 // shouldn't do that with float, array or structure unless to void
1986 if (!IS_VOID(getSpec(type)) &&
1987 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1988 werror(E_INCOMPAT_TYPES);
1992 } else { // from a pointer to a pointer
1993 if (IS_GENPTR(type) && IS_VOID(type->next))
1994 { // cast to void* is always allowed
1996 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
1997 { // cast from void* is always allowed
1999 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2000 // if not a pointer to a function
2001 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2002 if (implicit) { // if not to generic, they have to match
2003 if (!IS_GENPTR(type) &&
2004 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2005 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2009 werror(E_INCOMPAT_PTYPES);
2016 } else { // to a non pointer
2017 if (IS_PTR(optype)) { // from a pointer
2018 if (implicit) { // sneaky
2019 if (IS_INTEGRAL(type)) {
2020 werror(W_PTR2INTEGRAL_NOCAST);
2022 } else { // shouldn't do that with float, array or structure
2023 werror(E_INCOMPAT_TYPES);
2030 printFromToType (optype, type);
2033 /* if they are the same size create an assignment */
2035 /* This seems very dangerous to me, since there are several */
2036 /* optimizations (for example, gcse) that don't notice the */
2037 /* cast hidden in this assignement and may simplify an */
2038 /* iCode to use the original (uncasted) operand. */
2039 /* Unfortunately, other things break when this cast is */
2040 /* made explicit. Need to fix this someday. */
2041 /* -- EEP, 2004/01/21 */
2042 if (getSize (type) == getSize (optype) &&
2043 !IS_BITFIELD (type) &&
2045 !IS_FLOAT (optype) &&
2046 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2047 (!IS_SPEC (type) && !IS_SPEC (optype))))
2049 ic = newiCode ('=', NULL, op);
2050 IC_RESULT (ic) = newiTempOperand (type, 0);
2051 SPIL_LOC (IC_RESULT (ic)) =
2052 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2053 IC_RESULT (ic)->isaddr = 0;
2057 ic = newiCode (CAST, operandFromLink (type),
2058 geniCodeRValue (op, FALSE));
2060 IC_RESULT (ic) = newiTempOperand (type, 0);
2063 /* preserve the storage class & output class */
2064 /* of the original variable */
2065 restype = getSpec (operandType (IC_RESULT (ic)));
2066 if (!IS_LITERAL(opetype) &&
2069 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2070 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2073 return IC_RESULT (ic);
2076 /*-----------------------------------------------------------------*/
2077 /* geniCodeLabel - will create a Label */
2078 /*-----------------------------------------------------------------*/
2080 geniCodeLabel (symbol * label)
2084 ic = newiCodeLabelGoto (LABEL, label);
2088 /*-----------------------------------------------------------------*/
2089 /* geniCodeGoto - will create a Goto */
2090 /*-----------------------------------------------------------------*/
2092 geniCodeGoto (symbol * label)
2096 ic = newiCodeLabelGoto (GOTO, label);
2100 /*-----------------------------------------------------------------*/
2101 /* geniCodeMultiply - gen intermediate code for multiplication */
2102 /*-----------------------------------------------------------------*/
2104 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2111 /* if they are both literal then we know the result */
2112 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2113 return operandFromValue (valMult (left->operand.valOperand,
2114 right->operand.valOperand));
2116 if (IS_LITERAL(retype)) {
2117 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2120 resType = usualBinaryConversions (&left, &right, resultType, '*');
2122 rtype = operandType (right);
2123 retype = getSpec (rtype);
2124 ltype = operandType (left);
2125 letype = getSpec (ltype);
2128 /* if the right is a literal & power of 2 */
2129 /* then make it a left shift */
2130 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2131 efficient in most cases than 2 bytes result = 2 bytes << literal
2132 if port has 1 byte muldiv */
2133 if (p2 && !IS_FLOAT (letype)
2134 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2135 && (port->support.muldiv == 1))
2136 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2137 && strcmp (port->target, "pic14") != 0)
2139 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2141 /* LEFT_OP need same size for left and result, */
2142 left = geniCodeCast (resType, left, TRUE);
2143 ltype = operandType (left);
2145 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2149 ic = newiCode ('*', left, right); /* normal multiplication */
2150 /* if the size left or right > 1 then support routine */
2151 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2155 IC_RESULT (ic) = newiTempOperand (resType, 1);
2158 return IC_RESULT (ic);
2161 /*-----------------------------------------------------------------*/
2162 /* geniCodeDivision - gen intermediate code for division */
2163 /*-----------------------------------------------------------------*/
2165 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2170 sym_link *rtype = operandType (right);
2171 sym_link *retype = getSpec (rtype);
2172 sym_link *ltype = operandType (left);
2173 sym_link *letype = getSpec (ltype);
2175 resType = usualBinaryConversions (&left, &right, resultType, '/');
2177 /* if the right is a literal & power of 2
2178 and left is unsigned then make it a
2180 if (IS_LITERAL (retype) &&
2181 !IS_FLOAT (letype) &&
2182 IS_UNSIGNED(letype) &&
2183 (p2 = powof2 ((TYPE_UDWORD)
2184 floatFromVal (right->operand.valOperand)))) {
2185 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2189 ic = newiCode ('/', left, right); /* normal division */
2190 /* if the size left or right > 1 then support routine */
2191 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2194 IC_RESULT (ic) = newiTempOperand (resType, 0);
2197 return IC_RESULT (ic);
2199 /*-----------------------------------------------------------------*/
2200 /* geniCodeModulus - gen intermediate code for modulus */
2201 /*-----------------------------------------------------------------*/
2203 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2209 /* if they are both literal then we know the result */
2210 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2211 return operandFromValue (valMod (left->operand.valOperand,
2212 right->operand.valOperand));
2214 resType = usualBinaryConversions (&left, &right, resultType, '%');
2216 /* now they are the same size */
2217 ic = newiCode ('%', left, right);
2219 /* if the size left or right > 1 then support routine */
2220 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2222 IC_RESULT (ic) = newiTempOperand (resType, 0);
2225 return IC_RESULT (ic);
2228 /*-----------------------------------------------------------------*/
2229 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2230 /*-----------------------------------------------------------------*/
2232 geniCodePtrPtrSubtract (operand * left, operand * right)
2238 /* if they are both literals then */
2239 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2241 result = operandFromValue (valMinus (left->operand.valOperand,
2242 right->operand.valOperand));
2246 ic = newiCode ('-', left, right);
2248 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2252 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2256 // should we really do this? is this ANSI?
2257 return geniCodeDivision (result,
2258 operandFromLit (getSize (ltype->next)),
2262 /*-----------------------------------------------------------------*/
2263 /* geniCodeSubtract - generates code for subtraction */
2264 /*-----------------------------------------------------------------*/
2266 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2273 /* if they both pointers then */
2274 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2275 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2276 return geniCodePtrPtrSubtract (left, right);
2278 /* if they are both literal then we know the result */
2279 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2280 && left->isLiteral && right->isLiteral)
2281 return operandFromValue (valMinus (left->operand.valOperand,
2282 right->operand.valOperand));
2284 /* if left is an array or pointer */
2285 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2287 isarray = left->isaddr;
2288 right = geniCodeMultiply (right,
2289 operandFromLit (getSize (ltype->next)),
2290 (getArraySizePtr(left) >= INTSIZE) ?
2293 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2296 { /* make them the same size */
2297 resType = usualBinaryConversions (&left, &right, resultType, '-');
2300 ic = newiCode ('-', left, right);
2302 IC_RESULT (ic) = newiTempOperand (resType, 1);
2303 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2305 /* if left or right is a float */
2306 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2310 return IC_RESULT (ic);
2313 /*-----------------------------------------------------------------*/
2314 /* geniCodeAdd - generates iCode for addition */
2315 /*-----------------------------------------------------------------*/
2317 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2326 /* if the right side is LITERAL zero */
2327 /* return the left side */
2328 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2331 /* if left is literal zero return right */
2332 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2335 /* if left is a pointer then size */
2336 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2338 isarray = left->isaddr;
2339 // there is no need to multiply with 1
2340 if (getSize (ltype->next) != 1)
2342 size = operandFromLit (getSize (ltype->next));
2343 SPEC_USIGN (getSpec (operandType (size))) = 1;
2344 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2345 right = geniCodeMultiply (right,
2347 (getArraySizePtr(left) >= INTSIZE) ?
2350 /* Even if right is a 'unsigned char',
2351 the result will be a 'signed int' due to the promotion rules.
2352 It doesn't make sense when accessing arrays, so let's fix it here: */
2354 SPEC_USIGN (getSpec (operandType (right))) = 1;
2356 resType = copyLinkChain (ltype);
2359 { // make them the same size
2360 resType = usualBinaryConversions (&left, &right, resultType, '+');
2363 /* if they are both literals then we know */
2364 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2365 && left->isLiteral && right->isLiteral)
2366 return operandFromValue (valPlus (valFromType (ltype),
2367 valFromType (rtype)));
2369 ic = newiCode ('+', left, right);
2371 IC_RESULT (ic) = newiTempOperand (resType, 1);
2372 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2374 /* if left or right is a float then support
2376 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2381 return IC_RESULT (ic);
2385 /*-----------------------------------------------------------------*/
2386 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2387 /*-----------------------------------------------------------------*/
2389 aggrToPtr (sym_link * type, bool force)
2394 if (IS_PTR (type) && !force)
2397 etype = getSpec (type);
2398 ptype = newLink (DECLARATOR);
2402 /* set the pointer depending on the storage class */
2403 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2407 /*------------------------------------------------------------------*/
2408 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2409 /*------------------------------------------------------------------*/
2411 aggrToPtrDclType (sym_link * type, bool force)
2413 if (IS_PTR (type) && !force)
2414 return DCL_TYPE (type);
2416 /* return the pointer depending on the storage class */
2417 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2420 /*-----------------------------------------------------------------*/
2421 /* geniCodeArray2Ptr - array to pointer */
2422 /*-----------------------------------------------------------------*/
2424 geniCodeArray2Ptr (operand * op)
2426 sym_link *optype = operandType (op);
2427 sym_link *opetype = getSpec (optype);
2429 /* set the pointer depending on the storage class */
2430 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2437 /*-----------------------------------------------------------------*/
2438 /* geniCodeArray - array access */
2439 /*-----------------------------------------------------------------*/
2441 geniCodeArray (operand * left, operand * right, int lvl)
2445 sym_link *ltype = operandType (left);
2450 if (IS_PTR (ltype->next) && left->isaddr)
2452 left = geniCodeRValue (left, FALSE);
2455 return geniCodeDerefPtr (geniCodeAdd (left,
2457 (getArraySizePtr(left) >= INTSIZE) ?
2463 size = operandFromLit (getSize (ltype->next));
2464 SPEC_USIGN (getSpec (operandType (size))) = 1;
2465 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2466 right = geniCodeMultiply (right,
2468 (getArraySizePtr(left) >= INTSIZE) ?
2471 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2472 It doesn't make sense when accessing arrays, so let's fix it here: */
2474 SPEC_USIGN (getSpec (operandType (right))) = 1;
2475 /* we can check for limits here */
2476 /* already done in SDCCast.c
2477 if (isOperandLiteral (right) &&
2480 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2482 werror (W_IDX_OUT_OF_BOUNDS,
2483 (int) operandLitValue (right) / getSize (ltype->next),
2488 ic = newiCode ('+', left, right);
2490 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2491 !IS_AGGREGATE (ltype->next) &&
2492 !IS_PTR (ltype->next))
2493 ? ltype : ltype->next), 0);
2495 if (!IS_AGGREGATE (ltype->next))
2497 IC_RESULT (ic)->isaddr = 1;
2498 IC_RESULT (ic)->aggr2ptr = 1;
2502 return IC_RESULT (ic);
2505 /*-----------------------------------------------------------------*/
2506 /* geniCodeStruct - generates intermediate code for structures */
2507 /*-----------------------------------------------------------------*/
2509 geniCodeStruct (operand * left, operand * right, bool islval)
2512 sym_link *type = operandType (left);
2513 sym_link *etype = getSpec (type);
2515 symbol *element = getStructElement (SPEC_STRUCT (etype),
2516 right->operand.symOperand);
2518 wassert(IS_SYMOP(right));
2520 /* add the offset */
2521 ic = newiCode ('+', left, operandFromLit (element->offset));
2523 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2525 /* preserve the storage & output class of the struct */
2526 /* as well as the volatile attribute */
2527 retype = getSpec (operandType (IC_RESULT (ic)));
2528 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2529 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2530 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2531 SPEC_CONST (retype) |= SPEC_CONST (etype);
2533 if (IS_PTR (element->type))
2534 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2536 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2539 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2542 /*-----------------------------------------------------------------*/
2543 /* geniCodePostInc - generate int code for Post increment */
2544 /*-----------------------------------------------------------------*/
2546 geniCodePostInc (operand * op)
2550 sym_link *optype = operandType (op);
2552 operand *rv = (IS_ITEMP (op) ?
2553 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2555 sym_link *rvtype = operandType (rv);
2558 /* if this is not an address we have trouble */
2561 werror (E_LVALUE_REQUIRED, "++");
2565 rOp = newiTempOperand (rvtype, 0);
2566 OP_SYMBOL(rOp)->noSpilLoc = 1;
2569 OP_SYMBOL(rv)->noSpilLoc = 1;
2571 geniCodeAssign (rOp, rv, 0, 0);
2573 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2575 werror(W_SIZEOF_VOID);
2576 if (IS_FLOAT (rvtype))
2577 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2579 ic = newiCode ('+', rv, operandFromLit (size));
2581 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2584 geniCodeAssign (op, result, 0, 0);
2590 /*-----------------------------------------------------------------*/
2591 /* geniCodePreInc - generate code for preIncrement */
2592 /*-----------------------------------------------------------------*/
2594 geniCodePreInc (operand * op, bool lvalue)
2597 sym_link *optype = operandType (op);
2598 operand *rop = (IS_ITEMP (op) ?
2599 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2601 sym_link *roptype = operandType (rop);
2607 werror (E_LVALUE_REQUIRED, "++");
2611 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2613 werror(W_SIZEOF_VOID);
2614 if (IS_FLOAT (roptype))
2615 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2617 ic = newiCode ('+', rop, operandFromLit (size));
2618 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2621 (void) geniCodeAssign (op, result, 0, 0);
2622 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2628 /*-----------------------------------------------------------------*/
2629 /* geniCodePostDec - generates code for Post decrement */
2630 /*-----------------------------------------------------------------*/
2632 geniCodePostDec (operand * op)
2636 sym_link *optype = operandType (op);
2638 operand *rv = (IS_ITEMP (op) ?
2639 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2641 sym_link *rvtype = operandType (rv);
2644 /* if this is not an address we have trouble */
2647 werror (E_LVALUE_REQUIRED, "--");
2651 rOp = newiTempOperand (rvtype, 0);
2652 OP_SYMBOL(rOp)->noSpilLoc = 1;
2655 OP_SYMBOL(rv)->noSpilLoc = 1;
2657 geniCodeAssign (rOp, rv, 0, 0);
2659 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2661 werror(W_SIZEOF_VOID);
2662 if (IS_FLOAT (rvtype))
2663 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2665 ic = newiCode ('-', rv, operandFromLit (size));
2667 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2670 geniCodeAssign (op, result, 0, 0);
2676 /*-----------------------------------------------------------------*/
2677 /* geniCodePreDec - generate code for pre decrement */
2678 /*-----------------------------------------------------------------*/
2680 geniCodePreDec (operand * op, bool lvalue)
2683 sym_link *optype = operandType (op);
2684 operand *rop = (IS_ITEMP (op) ?
2685 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2687 sym_link *roptype = operandType (rop);
2693 werror (E_LVALUE_REQUIRED, "--");
2697 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2699 werror(W_SIZEOF_VOID);
2700 if (IS_FLOAT (roptype))
2701 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2703 ic = newiCode ('-', rop, operandFromLit (size));
2704 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2707 (void) geniCodeAssign (op, result, 0, 0);
2708 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2715 /*-----------------------------------------------------------------*/
2716 /* geniCodeBitwise - gen int code for bitWise operators */
2717 /*-----------------------------------------------------------------*/
2719 geniCodeBitwise (operand * left, operand * right,
2720 int oper, sym_link * resType)
2724 left = geniCodeCast (resType, left, TRUE);
2725 right = geniCodeCast (resType, right, TRUE);
2727 ic = newiCode (oper, left, right);
2728 IC_RESULT (ic) = newiTempOperand (resType, 0);
2731 return IC_RESULT (ic);
2734 /*-----------------------------------------------------------------*/
2735 /* geniCodeAddressOf - gens icode for '&' address of operator */
2736 /*-----------------------------------------------------------------*/
2738 geniCodeAddressOf (operand * op)
2742 sym_link *optype = operandType (op);
2743 sym_link *opetype = getSpec (optype);
2745 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2747 op = operandFromOperand (op);
2752 /* lvalue check already done in decorateType */
2753 /* this must be a lvalue */
2754 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2755 /* werror (E_LVALUE_REQUIRED,"&"); */
2759 p = newLink (DECLARATOR);
2761 /* set the pointer depending on the storage class */
2762 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2764 p->next = copyLinkChain (optype);
2766 /* if already a temp */
2769 setOperandType (op, p);
2774 /* other wise make this of the type coming in */
2775 ic = newiCode (ADDRESS_OF, op, NULL);
2776 IC_RESULT (ic) = newiTempOperand (p, 1);
2777 IC_RESULT (ic)->isaddr = 0;
2779 return IC_RESULT (ic);
2781 /*-----------------------------------------------------------------*/
2782 /* setOClass - sets the output class depending on the pointer type */
2783 /*-----------------------------------------------------------------*/
2785 setOClass (sym_link * ptr, sym_link * spec)
2787 switch (DCL_TYPE (ptr))
2790 SPEC_OCLS (spec) = data;
2794 SPEC_OCLS (spec) = generic;
2798 SPEC_OCLS (spec) = xdata;
2802 SPEC_OCLS (spec) = code;
2806 SPEC_OCLS (spec) = idata;
2810 SPEC_OCLS (spec) = xstack;
2814 SPEC_OCLS (spec) = eeprom;
2823 /*-----------------------------------------------------------------*/
2824 /* geniCodeDerefPtr - dereference pointer with '*' */
2825 /*-----------------------------------------------------------------*/
2827 geniCodeDerefPtr (operand * op,int lvl)
2829 sym_link *rtype, *retype;
2830 sym_link *optype = operandType (op);
2832 // if this is an array then array access
2833 if (IS_ARRAY (optype)) {
2834 // don't worry, this will be optimized out later
2835 return geniCodeArray (op, operandFromLit (0), lvl);
2838 // just in case someone screws up
2839 wassert (IS_PTR (optype));
2841 if (IS_TRUE_SYMOP (op))
2844 op = geniCodeRValue (op, TRUE);
2847 /* now get rid of the pointer part */
2848 if (isLvaluereq(lvl) && IS_ITEMP (op))
2850 retype = getSpec (rtype = copyLinkChain (optype));
2854 retype = getSpec (rtype = copyLinkChain (optype->next));
2855 /* outputclass needs 2b updated */
2856 setOClass (optype, retype);
2859 op->isGptr = IS_GENPTR (optype);
2861 op->isaddr = (IS_PTR (rtype) ||
2862 IS_STRUCT (rtype) ||
2867 if (!isLvaluereq(lvl))
2868 op = geniCodeRValue (op, TRUE);
2870 setOperandType (op, rtype);
2875 /*-----------------------------------------------------------------*/
2876 /* geniCodeUnaryMinus - does a unary minus of the operand */
2877 /*-----------------------------------------------------------------*/
2879 geniCodeUnaryMinus (operand * op)
2882 sym_link *optype = operandType (op);
2884 if (IS_LITERAL (optype))
2885 return operandFromLit (-floatFromVal (op->operand.valOperand));
2887 ic = newiCode (UNARYMINUS, op, NULL);
2888 IC_RESULT (ic) = newiTempOperand (optype, 0);
2890 return IC_RESULT (ic);
2893 /*-----------------------------------------------------------------*/
2894 /* geniCodeLeftShift - gen i code for left shift */
2895 /*-----------------------------------------------------------------*/
2897 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2902 ic = newiCode (LEFT_OP, left, right);
2904 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2905 IC_RESULT (ic) = newiTempOperand (resType, 0);
2907 return IC_RESULT (ic);
2910 /*-----------------------------------------------------------------*/
2911 /* geniCodeRightShift - gen i code for right shift */
2912 /*-----------------------------------------------------------------*/
2914 geniCodeRightShift (operand * left, operand * right)
2918 ic = newiCode (RIGHT_OP, left, right);
2919 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2921 return IC_RESULT (ic);
2924 /*-----------------------------------------------------------------*/
2925 /* geniCodeLogic- logic code */
2926 /*-----------------------------------------------------------------*/
2928 geniCodeLogic (operand * left, operand * right, int op)
2932 sym_link *rtype = operandType (right);
2933 sym_link *ltype = operandType (left);
2935 /* left is integral type and right is literal then
2936 check if the literal value is within bounds */
2937 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2939 checkConstantRange(ltype,
2940 OP_VALUE(right), "compare operation", 1);
2943 /* if one operand is a pointer and the other is a literal generic void pointer,
2944 change the type of the literal generic void pointer to match the other pointer */
2945 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2946 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2948 /* find left's definition */
2949 ic = (iCode *) setFirstItem (iCodeChain);
2952 if (((ic->op == CAST) || (ic->op == '='))
2953 && isOperandEqual(left, IC_RESULT (ic)))
2956 ic = setNextItem (iCodeChain);
2958 /* if casting literal to generic pointer, then cast to rtype instead */
2959 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2961 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2962 ltype = operandType(left);
2965 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2966 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2968 /* find right's definition */
2969 ic = (iCode *) setFirstItem (iCodeChain);
2972 if (((ic->op == CAST) || (ic->op == '='))
2973 && isOperandEqual(right, IC_RESULT (ic)))
2976 ic = setNextItem (iCodeChain);
2978 /* if casting literal to generic pointer, then cast to rtype instead */
2979 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2981 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2982 rtype = operandType(right);
2986 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2988 ic = newiCode (op, left, right);
2989 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2991 /* if comparing float
2992 and not a '==' || '!=' || '&&' || '||' (these
2994 if (IS_FLOAT(ctype) &&
3002 return IC_RESULT (ic);
3005 /*-----------------------------------------------------------------*/
3006 /* geniCodeLogicAndOr - && || operations */
3007 /*-----------------------------------------------------------------*/
3009 geniCodeLogicAndOr (ast *tree, int lvl)
3012 symbol *falseLabel = newiTempLabel (NULL);
3013 symbol *trueLabel = newiTempLabel (NULL);
3014 symbol *exitLabel = newiTempLabel (NULL);
3015 operand *op, *result, *condition;
3017 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3018 They can be reenabled by executing the following block. If you find
3019 a decent optimization you could start right here:
3024 operand *leftOp, *rightOp;
3026 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3027 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3029 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3033 /* generate two IFX for the '&&' or '||' op */
3035 /* evaluate left operand */
3036 condition = ast2iCode (tree->left, lvl + 1);
3037 op = geniCodeRValue (condition, FALSE);
3039 /* test left operand */
3040 if (tree->opval.op == AND_OP)
3041 ic = newiCodeCondition (op, NULL, falseLabel);
3043 ic = newiCodeCondition (op, trueLabel, NULL);
3046 /* evaluate right operand */
3047 condition = ast2iCode (tree->right, lvl + 1);
3048 op = geniCodeRValue (condition, FALSE);
3050 /* test right operand */
3051 ic = newiCodeCondition (op, trueLabel, NULL);
3054 /* store 0 or 1 in result */
3055 result = newiTempOperand (newCharLink(), 1);
3057 geniCodeLabel (falseLabel);
3058 geniCodeAssign (result, operandFromLit (0), 0, 0);
3059 /* generate an unconditional goto */
3060 geniCodeGoto (exitLabel);
3062 geniCodeLabel (trueLabel);
3063 geniCodeAssign (result, operandFromLit (1), 0, 0);
3065 geniCodeLabel (exitLabel);
3070 /*-----------------------------------------------------------------*/
3071 /* geniCodeUnary - for a a generic unary operation */
3072 /*-----------------------------------------------------------------*/
3074 geniCodeUnary (operand * op, int oper)
3076 iCode *ic = newiCode (oper, op, NULL);
3078 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3080 return IC_RESULT (ic);
3083 /*-----------------------------------------------------------------*/
3084 /* geniCodeConditional - geniCode for '?' ':' operation */
3085 /*-----------------------------------------------------------------*/
3087 geniCodeConditional (ast * tree,int lvl)
3090 symbol *falseLabel = newiTempLabel (NULL);
3091 symbol *exitLabel = newiTempLabel (NULL);
3092 operand *cond = ast2iCode (tree->left,lvl+1);
3093 operand *true, *false, *result;
3095 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3099 true = ast2iCode (tree->right->left,lvl+1);
3101 /* move the value to a new Operand */
3102 result = newiTempOperand (tree->right->ftype, 0);
3103 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3105 /* generate an unconditional goto */
3106 geniCodeGoto (exitLabel);
3108 /* now for the right side */
3109 geniCodeLabel (falseLabel);
3111 false = ast2iCode (tree->right->right,lvl+1);
3112 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3114 /* create the exit label */
3115 geniCodeLabel (exitLabel);
3120 /*-----------------------------------------------------------------*/
3121 /* geniCodeAssign - generate code for assignment */
3122 /*-----------------------------------------------------------------*/
3124 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3127 sym_link *ltype = operandType (left);
3128 sym_link *rtype = operandType (right);
3130 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3132 werror (E_LVALUE_REQUIRED, "assignment");
3136 /* left is integral type and right is literal then
3137 check if the literal value is within bounds */
3138 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3140 checkConstantRange(ltype,
3141 OP_VALUE(right), "= operation", 0);
3144 /* if the left & right type don't exactly match */
3145 /* if pointer set then make sure the check is
3146 done with the type & not the pointer */
3147 /* then cast rights type to left */
3149 /* first check the type for pointer assignement */
3150 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3151 compareType (ltype, rtype) <= 0)
3153 if (compareType (ltype->next, rtype) < 0)
3154 right = geniCodeCast (ltype->next, right, TRUE);
3156 else if (compareType (ltype, rtype) < 0)
3157 right = geniCodeCast (ltype, right, TRUE);
3159 /* If left is a true symbol & ! volatile
3160 create an assignment to temporary for
3161 the right & then assign this temporary
3162 to the symbol. This is SSA (static single
3163 assignment). Isn't it simple and folks have
3164 published mountains of paper on it */
3165 if (IS_TRUE_SYMOP (left) &&
3166 !isOperandVolatile (left, FALSE) &&
3167 isOperandGlobal (left))
3171 if (IS_TRUE_SYMOP (right))
3172 sym = OP_SYMBOL (right);
3173 ic = newiCode ('=', NULL, right);
3174 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3175 SPIL_LOC (right) = sym;
3179 ic = newiCode ('=', NULL, right);
3180 IC_RESULT (ic) = left;
3183 /* if left isgptr flag is set then support
3184 routine will be required */
3188 ic->nosupdate = nosupdate;
3192 /*-----------------------------------------------------------------*/
3193 /* geniCodeDummyRead - generate code for dummy read */
3194 /*-----------------------------------------------------------------*/
3196 geniCodeDummyRead (operand * op)
3199 sym_link *type = operandType (op);
3201 if (!IS_VOLATILE(type))
3204 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3210 /*-----------------------------------------------------------------*/
3211 /* geniCodeSEParms - generate code for side effecting fcalls */
3212 /*-----------------------------------------------------------------*/
3214 geniCodeSEParms (ast * parms,int lvl)
3219 if (parms->type == EX_OP && parms->opval.op == PARAM)
3221 geniCodeSEParms (parms->left,lvl);
3222 geniCodeSEParms (parms->right,lvl);
3226 /* hack don't like this but too lazy to think of
3228 if (IS_ADDRESS_OF_OP (parms))
3229 parms->left->lvalue = 1;
3231 if (IS_CAST_OP (parms) &&
3232 IS_PTR (parms->ftype) &&
3233 IS_ADDRESS_OF_OP (parms->right))
3234 parms->right->left->lvalue = 1;
3236 parms->opval.oprnd =
3237 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3239 parms->type = EX_OPERAND;
3240 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3241 SPEC_ARGREG(parms->ftype);
3244 /*-----------------------------------------------------------------*/
3245 /* geniCodeParms - generates parameters */
3246 /*-----------------------------------------------------------------*/
3248 geniCodeParms (ast * parms, value *argVals, int *stack,
3249 sym_link * ftype, int lvl)
3257 if (argVals==NULL) {
3259 argVals = FUNC_ARGS (ftype);
3262 /* if this is a param node then do the left & right */
3263 if (parms->type == EX_OP && parms->opval.op == PARAM)
3265 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3266 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3270 /* get the parameter value */
3271 if (parms->type == EX_OPERAND)
3272 pval = parms->opval.oprnd;
3275 /* maybe this else should go away ?? */
3276 /* hack don't like this but too lazy to think of
3278 if (IS_ADDRESS_OF_OP (parms))
3279 parms->left->lvalue = 1;
3281 if (IS_CAST_OP (parms) &&
3282 IS_PTR (parms->ftype) &&
3283 IS_ADDRESS_OF_OP (parms->right))
3284 parms->right->left->lvalue = 1;
3286 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3289 /* if register parm then make it a send */
3290 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3291 IFFUNC_ISBUILTIN(ftype))
3293 ic = newiCode (SEND, pval, NULL);
3294 ic->argreg = SPEC_ARGREG(parms->etype);
3295 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3300 /* now decide whether to push or assign */
3301 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3305 operand *top = operandFromSymbol (argVals->sym);
3306 /* clear useDef and other bitVectors */
3307 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3308 geniCodeAssign (top, pval, 1, 0);
3312 sym_link *p = operandType (pval);
3314 ic = newiCode (IPUSH, pval, NULL);
3316 /* update the stack adjustment */
3317 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3322 argVals=argVals->next;
3326 /*-----------------------------------------------------------------*/
3327 /* geniCodeCall - generates temp code for calling */
3328 /*-----------------------------------------------------------------*/
3330 geniCodeCall (operand * left, ast * parms,int lvl)
3334 sym_link *type, *etype;
3338 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3339 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3340 werror (E_FUNCTION_EXPECTED);
3341 return operandFromValue(valueFromLit(0));
3344 /* take care of parameters with side-effecting
3345 function calls in them, this is required to take care
3346 of overlaying function parameters */
3347 geniCodeSEParms (parms,lvl);
3349 ftype = operandType (left);
3350 if (IS_CODEPTR (ftype))
3351 ftype = ftype->next;
3353 /* first the parameters */
3354 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3356 /* now call : if symbol then pcall */
3357 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3358 ic = newiCode (PCALL, left, NULL);
3360 ic = newiCode (CALL, left, NULL);
3363 type = copyLinkChain (ftype->next);
3364 etype = getSpec (type);
3365 SPEC_EXTR (etype) = 0;
3366 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3370 /* stack adjustment after call */
3371 ic->parmBytes = stack;
3376 /*-----------------------------------------------------------------*/
3377 /* geniCodeReceive - generate intermediate code for "receive" */
3378 /*-----------------------------------------------------------------*/
3380 geniCodeReceive (value * args)
3382 unsigned char paramByteCounter = 0;
3384 /* for all arguments that are passed in registers */
3388 if (IS_REGPARM (args->etype))
3390 operand *opr = operandFromValue (args);
3392 symbol *sym = OP_SYMBOL (opr);
3395 /* we will use it after all optimizations
3396 and before liveRange calculation */
3397 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3400 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3401 options.stackAuto == 0 &&
3402 (!(options.model == MODEL_FLAT24)) )
3407 opl = newiTempOperand (args->type, 0);
3409 sym->reqv->key = sym->key;
3410 OP_SYMBOL (sym->reqv)->key = sym->key;
3411 OP_SYMBOL (sym->reqv)->isreqv = 1;
3412 OP_SYMBOL (sym->reqv)->islocal = 0;
3413 SPIL_LOC (sym->reqv) = sym;
3417 ic = newiCode (RECEIVE, NULL, NULL);
3418 ic->argreg = SPEC_ARGREG(args->etype);
3420 currFunc->recvSize = getSize (sym->type);
3423 IC_RESULT (ic) = opr;
3425 /* misuse of parmBytes (normally used for functions)
3426 * to save estimated stack position of this argument.
3427 * Normally this should be zero for RECEIVE iCodes.
3428 * No idea if this causes side effects on other ports. - dw
3430 ic->parmBytes = paramByteCounter;
3432 /* what stack position do we have? */
3433 paramByteCounter += getSize (sym->type);
3442 /*-----------------------------------------------------------------*/
3443 /* geniCodeFunctionBody - create the function body */
3444 /*-----------------------------------------------------------------*/
3446 geniCodeFunctionBody (ast * tree,int lvl)
3453 /* reset the auto generation */
3459 func = ast2iCode (tree->left,lvl+1);
3460 fetype = getSpec (operandType (func));
3462 savelineno = lineno;
3463 lineno = OP_SYMBOL (func)->lineDef;
3464 /* create an entry label */
3465 geniCodeLabel (entryLabel);
3466 lineno = savelineno;
3468 /* create a proc icode */
3469 ic = newiCode (FUNCTION, func, NULL);
3470 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3475 /* for all parameters that are passed
3476 on registers add a "receive" */
3477 geniCodeReceive (tree->values.args);
3479 /* generate code for the body */
3480 ast2iCode (tree->right,lvl+1);
3482 /* create a label for return */
3483 geniCodeLabel (returnLabel);
3485 /* now generate the end proc */
3486 ic = newiCode (ENDFUNCTION, func, NULL);
3492 /*-----------------------------------------------------------------*/
3493 /* geniCodeReturn - gen icode for 'return' statement */
3494 /*-----------------------------------------------------------------*/
3496 geniCodeReturn (operand * op)
3500 /* if the operand is present force an rvalue */
3502 op = geniCodeRValue (op, FALSE);
3504 ic = newiCode (RETURN, op, NULL);
3508 /*-----------------------------------------------------------------*/
3509 /* geniCodeIfx - generates code for extended if statement */
3510 /*-----------------------------------------------------------------*/
3512 geniCodeIfx (ast * tree,int lvl)
3515 operand *condition = ast2iCode (tree->left,lvl+1);
3518 /* if condition is null then exit */
3522 condition = geniCodeRValue (condition, FALSE);
3524 cetype = getSpec (operandType (condition));
3525 /* if the condition is a literal */
3526 if (IS_LITERAL (cetype))
3528 if (floatFromVal (condition->operand.valOperand))
3530 if (tree->trueLabel)
3531 geniCodeGoto (tree->trueLabel);
3537 if (tree->falseLabel)
3538 geniCodeGoto (tree->falseLabel);
3545 if (tree->trueLabel)
3547 ic = newiCodeCondition (condition,
3552 if (tree->falseLabel)
3553 geniCodeGoto (tree->falseLabel);
3557 ic = newiCodeCondition (condition,
3564 ast2iCode (tree->right,lvl+1);
3567 /*-----------------------------------------------------------------*/
3568 /* geniCodeJumpTable - tries to create a jump table for switch */
3569 /*-----------------------------------------------------------------*/
3571 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3573 int min, max, cnt = 1;
3580 int needRangeCheck = !optimize.noJTabBoundary
3581 || tree->values.switchVals.swDefault;
3582 sym_link *cetype = getSpec (operandType (cond));
3583 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3584 int sizeofMatchJump, sizeofJumpTable;
3587 if (!tree || !caseVals)
3590 /* the criteria for creating a jump table is */
3591 /* all integer numbers between the maximum & minimum must */
3592 /* be present , the maximum value should not exceed 255 */
3593 /* If not all integer numbers are present the algorithm */
3594 /* inserts jumps to the default label for the missing numbers */
3595 /* and decides later whether it is worth it */
3596 min = (int) floatFromVal (vch = caseVals);
3603 max = (int) floatFromVal (vch);
3605 /* Exit if the range is too large to handle with a jump table. */
3606 if (1 + max - min > port->jumptableCost.maxCount)
3609 switch (getSize (operandType (cond)))
3611 case 1: sizeIndex = 0; break;
3612 case 2: sizeIndex = 1; break;
3613 case 4: sizeIndex = 2; break;
3617 /* Compute the size cost of the range check and subtraction. */
3619 sizeofZeroMinCost = 0;
3623 if (!(min==0 && IS_UNSIGNED (cetype)))
3624 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3625 if (!IS_UNSIGNED (cetype))
3626 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3627 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3630 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3632 /* If the size cost of handling a non-zero minimum exceeds the */
3633 /* cost of extending the range down to zero, then it might be */
3634 /* better to extend the range to zero. */
3635 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3636 >= (min * port->jumptableCost.sizeofElement))
3638 /* Only extend the jump table if it would still be manageable. */
3639 if (1 + max <= port->jumptableCost.maxCount)
3642 if (IS_UNSIGNED (cetype))
3645 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3649 /* Compute the total size cost of a jump table. */
3650 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3651 + port->jumptableCost.sizeofDispatch
3652 + sizeofMinCost + sizeofMaxCost;
3654 /* Compute the total size cost of a match & jump sequence */
3655 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3657 /* If the size cost of the jump table is uneconomical then exit */
3658 if (sizeofMatchJump < sizeofJumpTable)
3661 /* The jump table is preferable. */
3663 /* First, a label for the default or missing cases. */
3664 if (tree->values.switchVals.swDefault)
3666 SNPRINTF (buffer, sizeof(buffer),
3668 tree->values.switchVals.swNum);
3672 SNPRINTF (buffer, sizeof(buffer),
3674 tree->values.switchVals.swNum);
3676 falseLabel = newiTempLabel (buffer);
3678 /* Build the list of labels for the jump table. */
3680 t = (int) floatFromVal (vch);
3681 for (i=min; i<=max; i++)
3685 /* Explicit case: make a new label for it. */
3686 SNPRINTF (buffer, sizeof(buffer),
3688 tree->values.switchVals.swNum,
3690 addSet (&labels, newiTempLabel (buffer));
3693 t = (int) floatFromVal (vch);
3697 /* Implicit case: use the default label. */
3698 addSet (&labels, falseLabel);
3702 /* If cond is volatile, it might change after the boundary */
3703 /* conditions are tested to an out of bounds value, causing */
3704 /* a jump to a location outside of the jump table. To avoid */
3705 /* this possibility, use a non-volatile copy of it instead. */
3706 if (IS_OP_VOLATILE (cond))
3711 newcond = newiTempOperand (operandType (cond), TRUE);
3712 newcond->isvolatile = 0;
3713 ic = newiCode ('=', NULL, cond);
3714 IC_RESULT (ic) = newcond;
3719 /* first we rule out the boundary conditions */
3720 /* if only optimization says so */
3723 sym_link *cetype = getSpec (operandType (cond));
3724 /* no need to check the lower bound if
3725 the condition is unsigned & minimum value is zero */
3726 if (!(min == 0 && IS_UNSIGNED (cetype)))
3728 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3729 ic = newiCodeCondition (boundary, falseLabel, NULL);
3733 /* now for upper bounds */
3734 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3735 ic = newiCodeCondition (boundary, falseLabel, NULL);
3739 /* if the min is not zero then we no make it zero */
3742 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3743 if (!IS_LITERAL(getSpec(operandType(cond))))
3744 setOperandType (cond, UCHARTYPE);
3747 /* now create the jumptable */
3748 ic = newiCode (JUMPTABLE, NULL, NULL);
3749 IC_JTCOND (ic) = cond;
3750 IC_JTLABELS (ic) = labels;
3755 /*-----------------------------------------------------------------*/
3756 /* geniCodeSwitch - changes a switch to a if statement */
3757 /*-----------------------------------------------------------------*/
3759 geniCodeSwitch (ast * tree,int lvl)
3762 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3763 value *caseVals = tree->values.switchVals.swVals;
3764 symbol *trueLabel, *falseLabel;
3766 /* If the condition is a literal, then just jump to the */
3767 /* appropriate case label. */
3768 if (IS_LITERAL(getSpec(operandType(cond))))
3770 int switchVal, caseVal;
3772 switchVal = (int) floatFromVal (cond->operand.valOperand);
3775 caseVal = (int) floatFromVal (caseVals);
3776 if (caseVal == switchVal)
3778 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3779 tree->values.switchVals.swNum, caseVal);
3780 trueLabel = newiTempLabel (buffer);
3781 geniCodeGoto (trueLabel);
3784 caseVals = caseVals->next;
3786 goto defaultOrBreak;
3789 /* if we can make this a jump table */
3790 if (geniCodeJumpTable (cond, caseVals, tree))
3791 goto jumpTable; /* no need for the comparison */
3793 /* for the cases defined do */
3797 operand *compare = geniCodeLogic (cond,
3798 operandFromValue (caseVals),
3801 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3802 tree->values.switchVals.swNum,
3803 (int) floatFromVal (caseVals));
3804 trueLabel = newiTempLabel (buffer);
3806 ic = newiCodeCondition (compare, trueLabel, NULL);
3808 caseVals = caseVals->next;
3813 /* if default is present then goto break else break */
3814 if (tree->values.switchVals.swDefault)
3816 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3820 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3823 falseLabel = newiTempLabel (buffer);
3824 geniCodeGoto (falseLabel);
3827 ast2iCode (tree->right,lvl+1);
3830 /*-----------------------------------------------------------------*/
3831 /* geniCodeInline - intermediate code for inline assembler */
3832 /*-----------------------------------------------------------------*/
3834 geniCodeInline (ast * tree)
3838 ic = newiCode (INLINEASM, NULL, NULL);
3839 IC_INLINE (ic) = tree->values.inlineasm;
3843 /*-----------------------------------------------------------------*/
3844 /* geniCodeArrayInit - intermediate code for array initializer */
3845 /*-----------------------------------------------------------------*/
3847 geniCodeArrayInit (ast * tree, operand *array)
3851 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3852 ic = newiCode (ARRAYINIT, array, NULL);
3853 IC_ARRAYILIST (ic) = tree->values.constlist;
3855 operand *left=newOperand(), *right=newOperand();
3856 left->type=right->type=SYMBOL;
3857 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3858 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3859 ic = newiCode (ARRAYINIT, left, right);
3864 /*-----------------------------------------------------------------*/
3865 /* geniCodeCritical - intermediate code for a critical statement */
3866 /*-----------------------------------------------------------------*/
3868 geniCodeCritical (ast *tree, int lvl)
3874 if (!options.stackAuto)
3876 type = newLink(SPECIFIER);
3877 SPEC_VOLATILE(type) = 1;
3878 SPEC_NOUN(type) = V_BIT;
3879 SPEC_SCLS(type) = S_BIT;
3880 SPEC_BLEN(type) = 1;
3881 SPEC_BSTR(type) = 0;
3882 op = newiTempOperand(type, 1);
3885 /* If op is NULL, the original interrupt state will saved on */
3886 /* the stack. Otherwise, it will be saved in op. */
3888 /* Generate a save of the current interrupt state & disable */
3889 ic = newiCode (CRITICAL, NULL, NULL);
3890 IC_RESULT (ic) = op;
3893 /* Generate the critical code sequence */
3894 if (tree->left && tree->left->type == EX_VALUE)
3895 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3897 ast2iCode (tree->left,lvl+1);
3899 /* Generate a restore of the original interrupt state */
3900 ic = newiCode (ENDCRITICAL, NULL, op);
3904 /*-----------------------------------------------------------------*/
3905 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3906 /* particular case. Ie : assigning or dereferencing array or ptr */
3907 /*-----------------------------------------------------------------*/
3908 set * lvaluereqSet = NULL;
3909 typedef struct lvalItem
3916 /*-----------------------------------------------------------------*/
3917 /* addLvaluereq - add a flag for lvalreq for current ast level */
3918 /*-----------------------------------------------------------------*/
3919 void addLvaluereq(int lvl)
3921 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3924 addSetHead(&lvaluereqSet,lpItem);
3927 /*-----------------------------------------------------------------*/
3928 /* delLvaluereq - del a flag for lvalreq for current ast level */
3929 /*-----------------------------------------------------------------*/
3933 lpItem = getSet(&lvaluereqSet);
3934 if(lpItem) Safe_free(lpItem);
3936 /*-----------------------------------------------------------------*/
3937 /* clearLvaluereq - clear lvalreq flag */
3938 /*-----------------------------------------------------------------*/
3939 void clearLvaluereq()
3942 lpItem = peekSet(lvaluereqSet);
3943 if(lpItem) lpItem->req = 0;
3945 /*-----------------------------------------------------------------*/
3946 /* getLvaluereq - get the last lvalreq level */
3947 /*-----------------------------------------------------------------*/
3948 int getLvaluereqLvl()
3951 lpItem = peekSet(lvaluereqSet);
3952 if(lpItem) return lpItem->lvl;
3955 /*-----------------------------------------------------------------*/
3956 /* isLvaluereq - is lvalreq valid for this level ? */
3957 /*-----------------------------------------------------------------*/
3958 int isLvaluereq(int lvl)
3961 lpItem = peekSet(lvaluereqSet);
3962 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3966 /*-----------------------------------------------------------------*/
3967 /* ast2iCode - creates an icodeList from an ast */
3968 /*-----------------------------------------------------------------*/
3970 ast2iCode (ast * tree,int lvl)
3972 operand *left = NULL;
3973 operand *right = NULL;
3977 /* set the global variables for filename & line number */
3979 filename = tree->filename;
3981 lineno = tree->lineno;
3983 block = tree->block;
3985 scopeLevel = tree->level;
3987 seqPoint = tree->seqPoint;
3989 if (tree->type == EX_VALUE)
3990 return operandFromValue (tree->opval.val);
3992 if (tree->type == EX_LINK)
3993 return operandFromLink (tree->opval.lnk);
3995 /* if we find a nullop */
3996 if (tree->type == EX_OP &&
3997 (tree->opval.op == NULLOP ||
3998 tree->opval.op == BLOCK))
4000 if (tree->left && tree->left->type == EX_VALUE)
4001 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4003 ast2iCode (tree->left,lvl+1);
4004 if (tree->right && tree->right->type == EX_VALUE)
4005 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4007 ast2iCode (tree->right,lvl+1);
4011 /* special cases for not evaluating */
4012 if (tree->opval.op != ':' &&
4013 tree->opval.op != '?' &&
4014 tree->opval.op != CALL &&
4015 tree->opval.op != IFX &&
4016 tree->opval.op != AND_OP &&
4017 tree->opval.op != OR_OP &&
4018 tree->opval.op != LABEL &&
4019 tree->opval.op != GOTO &&
4020 tree->opval.op != SWITCH &&
4021 tree->opval.op != FUNCTION &&
4022 tree->opval.op != INLINEASM &&
4023 tree->opval.op != CRITICAL)
4026 if (IS_ASSIGN_OP (tree->opval.op) ||
4027 IS_DEREF_OP (tree) ||
4028 (tree->opval.op == '&' && !tree->right) ||
4029 tree->opval.op == PTR_OP)
4032 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4033 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4036 left = operandFromAst (tree->left,lvl);
4038 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4039 left = geniCodeRValue (left, TRUE);
4043 left = operandFromAst (tree->left,lvl);
4045 if (tree->opval.op == INC_OP ||
4046 tree->opval.op == DEC_OP)
4049 right = operandFromAst (tree->right,lvl);
4054 right = operandFromAst (tree->right,lvl);
4058 /* now depending on the type of operand */
4059 /* this will be a biggy */
4060 switch (tree->opval.op)
4063 case '[': /* array operation */
4065 //sym_link *ltype = operandType (left);
4066 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4067 left = geniCodeRValue (left, FALSE);
4068 right = geniCodeRValue (right, TRUE);
4071 return geniCodeArray (left, right,lvl);
4073 case '.': /* structure dereference */
4074 if (IS_PTR (operandType (left)))
4075 left = geniCodeRValue (left, TRUE);
4077 left = geniCodeRValue (left, FALSE);
4079 return geniCodeStruct (left, right, tree->lvalue);
4081 case PTR_OP: /* structure pointer dereference */
4084 pType = operandType (left);
4085 left = geniCodeRValue (left, TRUE);
4087 setOClass (pType, getSpec (operandType (left)));
4090 return geniCodeStruct (left, right, tree->lvalue);
4092 case INC_OP: /* increment operator */
4094 return geniCodePostInc (left);
4096 return geniCodePreInc (right, tree->lvalue);
4098 case DEC_OP: /* decrement operator */
4100 return geniCodePostDec (left);
4102 return geniCodePreDec (right, tree->lvalue);
4104 case '&': /* bitwise and or address of operator */
4106 { /* this is a bitwise operator */
4107 left = geniCodeRValue (left, FALSE);
4108 right = geniCodeRValue (right, FALSE);
4109 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4112 return geniCodeAddressOf (left);
4114 case '|': /* bitwise or & xor */
4116 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4117 geniCodeRValue (right, FALSE),
4122 return geniCodeDivision (geniCodeRValue (left, FALSE),
4123 geniCodeRValue (right, FALSE),
4124 getResultTypeFromType (tree->ftype));
4127 return geniCodeModulus (geniCodeRValue (left, FALSE),
4128 geniCodeRValue (right, FALSE),
4129 getResultTypeFromType (tree->ftype));
4132 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4133 geniCodeRValue (right, FALSE),
4134 getResultTypeFromType (tree->ftype));
4136 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4140 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4141 geniCodeRValue (right, FALSE),
4142 getResultTypeFromType (tree->ftype));
4144 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4148 return geniCodeAdd (geniCodeRValue (left, FALSE),
4149 geniCodeRValue (right, FALSE),
4150 getResultTypeFromType (tree->ftype),
4153 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4156 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4157 geniCodeRValue (right, FALSE),
4158 getResultTypeFromType (tree->ftype));
4161 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4162 geniCodeRValue (right, FALSE));
4164 #if 0 // this indeed needs a second thought
4168 // let's keep this simple: get the rvalue we need
4169 op=geniCodeRValue (right, FALSE);
4170 // now cast it to whatever we want
4171 op=geniCodeCast (operandType(left), op, FALSE);
4172 // if this is going to be used as an lvalue, make it so
4178 #else // bug #604575, is it a bug ????
4179 return geniCodeCast (operandType (left),
4180 geniCodeRValue (right, FALSE), FALSE);
4187 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4192 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4193 setOperandType (op, UCHARTYPE);
4198 return geniCodeLogicAndOr (tree, lvl);
4205 /* different compilers (even different gccs) evaluate
4206 the two calls in a different order. to get the same
4207 result on all machines we've to specify a clear sequence.
4208 return geniCodeLogic (geniCodeRValue (left, FALSE),
4209 geniCodeRValue (right, FALSE),
4213 operand *leftOp, *rightOp;
4215 leftOp = geniCodeRValue (left , FALSE);
4216 rightOp = geniCodeRValue (right, FALSE);
4218 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4221 return geniCodeConditional (tree,lvl);
4224 return operandFromLit (getSize (tree->right->ftype));
4228 sym_link *rtype = operandType (right);
4229 sym_link *ltype = operandType (left);
4230 if (IS_PTR (rtype) && IS_ITEMP (right)
4231 && right->isaddr && compareType (rtype->next, ltype) == 1)
4232 right = geniCodeRValue (right, TRUE);
4234 right = geniCodeRValue (right, FALSE);
4236 geniCodeAssign (left, right, 0, 1);
4241 geniCodeAssign (left,
4242 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4244 geniCodeRValue (right, FALSE),
4245 getResultTypeFromType (tree->ftype)),
4250 geniCodeAssign (left,
4251 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4253 geniCodeRValue (right, FALSE),
4254 getResultTypeFromType (tree->ftype)),
4258 geniCodeAssign (left,
4259 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4261 geniCodeRValue (right, FALSE),
4262 getResultTypeFromType (tree->ftype)),
4266 sym_link *rtype = operandType (right);
4267 sym_link *ltype = operandType (left);
4268 if (IS_PTR (rtype) && IS_ITEMP (right)
4269 && right->isaddr && compareType (rtype->next, ltype) == 1)
4270 right = geniCodeRValue (right, TRUE);
4272 right = geniCodeRValue (right, FALSE);
4275 return geniCodeAssign (left,
4276 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4279 getResultTypeFromType (tree->ftype),
4285 sym_link *rtype = operandType (right);
4286 sym_link *ltype = operandType (left);
4287 if (IS_PTR (rtype) && IS_ITEMP (right)
4288 && right->isaddr && compareType (rtype->next, ltype) == 1)
4290 right = geniCodeRValue (right, TRUE);
4294 right = geniCodeRValue (right, FALSE);
4297 geniCodeAssign (left,
4298 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4301 getResultTypeFromType (tree->ftype)),
4306 geniCodeAssign (left,
4307 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4309 geniCodeRValue (right, FALSE),
4310 getResultTypeFromType (tree->ftype)),
4314 geniCodeAssign (left,
4315 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4317 geniCodeRValue (right, FALSE)), 0, 1);
4320 geniCodeAssign (left,
4321 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4323 geniCodeRValue (right, FALSE),
4325 operandType (left)), 0, 1);
4328 geniCodeAssign (left,
4329 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4331 geniCodeRValue (right, FALSE),
4333 operandType (left)), 0, 1);
4336 geniCodeAssign (left,
4337 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4339 geniCodeRValue (right, FALSE),
4341 operandType (left)), 0, 1);
4343 return geniCodeRValue (right, FALSE);
4346 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4349 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4350 return ast2iCode (tree->right,lvl+1);
4353 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4354 return ast2iCode (tree->right,lvl+1);
4357 geniCodeFunctionBody (tree,lvl);
4361 geniCodeReturn (right);
4365 geniCodeIfx (tree,lvl);
4369 geniCodeSwitch (tree,lvl);
4373 geniCodeInline (tree);
4377 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4381 geniCodeCritical (tree, lvl);
4387 /*-----------------------------------------------------------------*/
4388 /* reverseICChain - gets from the list and creates a linkedlist */
4389 /*-----------------------------------------------------------------*/
4396 while ((loop = getSet (&iCodeChain)))
4408 /*-----------------------------------------------------------------*/
4409 /* iCodeFromAst - given an ast will convert it to iCode */
4410 /*-----------------------------------------------------------------*/
4412 iCodeFromAst (ast * tree)
4414 returnLabel = newiTempLabel ("_return");
4415 entryLabel = newiTempLabel ("_entry");
4417 return reverseiCChain ();
4420 static const char *opTypeToStr(OPTYPE op)
4424 case SYMBOL: return "symbol";
4425 case VALUE: return "value";
4426 case TYPE: return "type";
4428 return "undefined type";
4432 operand *validateOpType(operand *op,
4439 if (op && op->type == type)
4444 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4445 " expected %s, got %s\n",
4446 macro, args, file, line,
4447 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4449 return op; // never reached, makes compiler happy.