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 /* for all arguments that are passed in registers */
3386 if (IS_REGPARM (args->etype))
3388 operand *opr = operandFromValue (args);
3390 symbol *sym = OP_SYMBOL (opr);
3393 /* we will use it after all optimizations
3394 and before liveRange calculation */
3395 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3398 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3399 options.stackAuto == 0 &&
3400 (!(options.model == MODEL_FLAT24)) )
3405 opl = newiTempOperand (args->type, 0);
3407 sym->reqv->key = sym->key;
3408 OP_SYMBOL (sym->reqv)->key = sym->key;
3409 OP_SYMBOL (sym->reqv)->isreqv = 1;
3410 OP_SYMBOL (sym->reqv)->islocal = 0;
3411 SPIL_LOC (sym->reqv) = sym;
3415 ic = newiCode (RECEIVE, NULL, NULL);
3416 ic->argreg = SPEC_ARGREG(args->etype);
3418 currFunc->recvSize = getSize (sym->type);
3421 IC_RESULT (ic) = opr;
3429 /*-----------------------------------------------------------------*/
3430 /* geniCodeFunctionBody - create the function body */
3431 /*-----------------------------------------------------------------*/
3433 geniCodeFunctionBody (ast * tree,int lvl)
3440 /* reset the auto generation */
3446 func = ast2iCode (tree->left,lvl+1);
3447 fetype = getSpec (operandType (func));
3449 savelineno = lineno;
3450 lineno = OP_SYMBOL (func)->lineDef;
3451 /* create an entry label */
3452 geniCodeLabel (entryLabel);
3453 lineno = savelineno;
3455 /* create a proc icode */
3456 ic = newiCode (FUNCTION, func, NULL);
3457 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3462 /* for all parameters that are passed
3463 on registers add a "receive" */
3464 geniCodeReceive (tree->values.args);
3466 /* generate code for the body */
3467 ast2iCode (tree->right,lvl+1);
3469 /* create a label for return */
3470 geniCodeLabel (returnLabel);
3472 /* now generate the end proc */
3473 ic = newiCode (ENDFUNCTION, func, NULL);
3479 /*-----------------------------------------------------------------*/
3480 /* geniCodeReturn - gen icode for 'return' statement */
3481 /*-----------------------------------------------------------------*/
3483 geniCodeReturn (operand * op)
3487 /* if the operand is present force an rvalue */
3489 op = geniCodeRValue (op, FALSE);
3491 ic = newiCode (RETURN, op, NULL);
3495 /*-----------------------------------------------------------------*/
3496 /* geniCodeIfx - generates code for extended if statement */
3497 /*-----------------------------------------------------------------*/
3499 geniCodeIfx (ast * tree,int lvl)
3502 operand *condition = ast2iCode (tree->left,lvl+1);
3505 /* if condition is null then exit */
3509 condition = geniCodeRValue (condition, FALSE);
3511 cetype = getSpec (operandType (condition));
3512 /* if the condition is a literal */
3513 if (IS_LITERAL (cetype))
3515 if (floatFromVal (condition->operand.valOperand))
3517 if (tree->trueLabel)
3518 geniCodeGoto (tree->trueLabel);
3524 if (tree->falseLabel)
3525 geniCodeGoto (tree->falseLabel);
3532 if (tree->trueLabel)
3534 ic = newiCodeCondition (condition,
3539 if (tree->falseLabel)
3540 geniCodeGoto (tree->falseLabel);
3544 ic = newiCodeCondition (condition,
3551 ast2iCode (tree->right,lvl+1);
3554 /*-----------------------------------------------------------------*/
3555 /* geniCodeJumpTable - tries to create a jump table for switch */
3556 /*-----------------------------------------------------------------*/
3558 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3560 int min, max, cnt = 1;
3567 int needRangeCheck = !optimize.noJTabBoundary
3568 || tree->values.switchVals.swDefault;
3569 sym_link *cetype = getSpec (operandType (cond));
3570 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3571 int sizeofMatchJump, sizeofJumpTable;
3574 if (!tree || !caseVals)
3577 /* the criteria for creating a jump table is */
3578 /* all integer numbers between the maximum & minimum must */
3579 /* be present , the maximum value should not exceed 255 */
3580 /* If not all integer numbers are present the algorithm */
3581 /* inserts jumps to the default label for the missing numbers */
3582 /* and decides later whether it is worth it */
3583 min = (int) floatFromVal (vch = caseVals);
3590 max = (int) floatFromVal (vch);
3592 /* Exit if the range is too large to handle with a jump table. */
3593 if (1 + max - min > port->jumptableCost.maxCount)
3596 switch (getSize (operandType (cond)))
3598 case 1: sizeIndex = 0; break;
3599 case 2: sizeIndex = 1; break;
3600 case 4: sizeIndex = 2; break;
3604 /* Compute the size cost of the range check and subtraction. */
3606 sizeofZeroMinCost = 0;
3610 if (!(min==0 && IS_UNSIGNED (cetype)))
3611 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3612 if (!IS_UNSIGNED (cetype))
3613 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3614 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3617 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3619 /* If the size cost of handling a non-zero minimum exceeds the */
3620 /* cost of extending the range down to zero, then it might be */
3621 /* better to extend the range to zero. */
3622 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3623 >= (min * port->jumptableCost.sizeofElement))
3625 /* Only extend the jump table if it would still be manageable. */
3626 if (1 + max <= port->jumptableCost.maxCount)
3629 if (IS_UNSIGNED (cetype))
3632 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3636 /* Compute the total size cost of a jump table. */
3637 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3638 + port->jumptableCost.sizeofDispatch
3639 + sizeofMinCost + sizeofMaxCost;
3641 /* Compute the total size cost of a match & jump sequence */
3642 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3644 /* If the size cost of the jump table is uneconomical then exit */
3645 if (sizeofMatchJump < sizeofJumpTable)
3648 /* The jump table is preferable. */
3650 /* First, a label for the default or missing cases. */
3651 if (tree->values.switchVals.swDefault)
3653 SNPRINTF (buffer, sizeof(buffer),
3655 tree->values.switchVals.swNum);
3659 SNPRINTF (buffer, sizeof(buffer),
3661 tree->values.switchVals.swNum);
3663 falseLabel = newiTempLabel (buffer);
3665 /* Build the list of labels for the jump table. */
3667 t = (int) floatFromVal (vch);
3668 for (i=min; i<=max; i++)
3672 /* Explicit case: make a new label for it. */
3673 SNPRINTF (buffer, sizeof(buffer),
3675 tree->values.switchVals.swNum,
3677 addSet (&labels, newiTempLabel (buffer));
3680 t = (int) floatFromVal (vch);
3684 /* Implicit case: use the default label. */
3685 addSet (&labels, falseLabel);
3689 /* If cond is volatile, it might change after the boundary */
3690 /* conditions are tested to an out of bounds value, causing */
3691 /* a jump to a location outside of the jump table. To avoid */
3692 /* this possibility, use a non-volatile copy of it instead. */
3693 if (IS_OP_VOLATILE (cond))
3698 newcond = newiTempOperand (operandType (cond), TRUE);
3699 newcond->isvolatile = 0;
3700 ic = newiCode ('=', NULL, cond);
3701 IC_RESULT (ic) = newcond;
3706 /* first we rule out the boundary conditions */
3707 /* if only optimization says so */
3710 sym_link *cetype = getSpec (operandType (cond));
3711 /* no need to check the lower bound if
3712 the condition is unsigned & minimum value is zero */
3713 if (!(min == 0 && IS_UNSIGNED (cetype)))
3715 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3716 ic = newiCodeCondition (boundary, falseLabel, NULL);
3720 /* now for upper bounds */
3721 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3722 ic = newiCodeCondition (boundary, falseLabel, NULL);
3726 /* if the min is not zero then we no make it zero */
3729 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3730 if (!IS_LITERAL(getSpec(operandType(cond))))
3731 setOperandType (cond, UCHARTYPE);
3734 /* now create the jumptable */
3735 ic = newiCode (JUMPTABLE, NULL, NULL);
3736 IC_JTCOND (ic) = cond;
3737 IC_JTLABELS (ic) = labels;
3742 /*-----------------------------------------------------------------*/
3743 /* geniCodeSwitch - changes a switch to a if statement */
3744 /*-----------------------------------------------------------------*/
3746 geniCodeSwitch (ast * tree,int lvl)
3749 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3750 value *caseVals = tree->values.switchVals.swVals;
3751 symbol *trueLabel, *falseLabel;
3753 /* If the condition is a literal, then just jump to the */
3754 /* appropriate case label. */
3755 if (IS_LITERAL(getSpec(operandType(cond))))
3757 int switchVal, caseVal;
3759 switchVal = (int) floatFromVal (cond->operand.valOperand);
3762 caseVal = (int) floatFromVal (caseVals);
3763 if (caseVal == switchVal)
3765 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3766 tree->values.switchVals.swNum, caseVal);
3767 trueLabel = newiTempLabel (buffer);
3768 geniCodeGoto (trueLabel);
3771 caseVals = caseVals->next;
3773 goto defaultOrBreak;
3776 /* if we can make this a jump table */
3777 if (geniCodeJumpTable (cond, caseVals, tree))
3778 goto jumpTable; /* no need for the comparison */
3780 /* for the cases defined do */
3784 operand *compare = geniCodeLogic (cond,
3785 operandFromValue (caseVals),
3788 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3789 tree->values.switchVals.swNum,
3790 (int) floatFromVal (caseVals));
3791 trueLabel = newiTempLabel (buffer);
3793 ic = newiCodeCondition (compare, trueLabel, NULL);
3795 caseVals = caseVals->next;
3800 /* if default is present then goto break else break */
3801 if (tree->values.switchVals.swDefault)
3803 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3807 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3810 falseLabel = newiTempLabel (buffer);
3811 geniCodeGoto (falseLabel);
3814 ast2iCode (tree->right,lvl+1);
3817 /*-----------------------------------------------------------------*/
3818 /* geniCodeInline - intermediate code for inline assembler */
3819 /*-----------------------------------------------------------------*/
3821 geniCodeInline (ast * tree)
3825 ic = newiCode (INLINEASM, NULL, NULL);
3826 IC_INLINE (ic) = tree->values.inlineasm;
3830 /*-----------------------------------------------------------------*/
3831 /* geniCodeArrayInit - intermediate code for array initializer */
3832 /*-----------------------------------------------------------------*/
3834 geniCodeArrayInit (ast * tree, operand *array)
3838 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3839 ic = newiCode (ARRAYINIT, array, NULL);
3840 IC_ARRAYILIST (ic) = tree->values.constlist;
3842 operand *left=newOperand(), *right=newOperand();
3843 left->type=right->type=SYMBOL;
3844 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3845 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3846 ic = newiCode (ARRAYINIT, left, right);
3851 /*-----------------------------------------------------------------*/
3852 /* geniCodeCritical - intermediate code for a critical statement */
3853 /*-----------------------------------------------------------------*/
3855 geniCodeCritical (ast *tree, int lvl)
3861 if (!options.stackAuto)
3863 type = newLink(SPECIFIER);
3864 SPEC_VOLATILE(type) = 1;
3865 SPEC_NOUN(type) = V_BIT;
3866 SPEC_SCLS(type) = S_BIT;
3867 SPEC_BLEN(type) = 1;
3868 SPEC_BSTR(type) = 0;
3869 op = newiTempOperand(type, 1);
3872 /* If op is NULL, the original interrupt state will saved on */
3873 /* the stack. Otherwise, it will be saved in op. */
3875 /* Generate a save of the current interrupt state & disable */
3876 ic = newiCode (CRITICAL, NULL, NULL);
3877 IC_RESULT (ic) = op;
3880 /* Generate the critical code sequence */
3881 if (tree->left && tree->left->type == EX_VALUE)
3882 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3884 ast2iCode (tree->left,lvl+1);
3886 /* Generate a restore of the original interrupt state */
3887 ic = newiCode (ENDCRITICAL, NULL, op);
3891 /*-----------------------------------------------------------------*/
3892 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3893 /* particular case. Ie : assigning or dereferencing array or ptr */
3894 /*-----------------------------------------------------------------*/
3895 set * lvaluereqSet = NULL;
3896 typedef struct lvalItem
3903 /*-----------------------------------------------------------------*/
3904 /* addLvaluereq - add a flag for lvalreq for current ast level */
3905 /*-----------------------------------------------------------------*/
3906 void addLvaluereq(int lvl)
3908 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3911 addSetHead(&lvaluereqSet,lpItem);
3914 /*-----------------------------------------------------------------*/
3915 /* delLvaluereq - del a flag for lvalreq for current ast level */
3916 /*-----------------------------------------------------------------*/
3920 lpItem = getSet(&lvaluereqSet);
3921 if(lpItem) Safe_free(lpItem);
3923 /*-----------------------------------------------------------------*/
3924 /* clearLvaluereq - clear lvalreq flag */
3925 /*-----------------------------------------------------------------*/
3926 void clearLvaluereq()
3929 lpItem = peekSet(lvaluereqSet);
3930 if(lpItem) lpItem->req = 0;
3932 /*-----------------------------------------------------------------*/
3933 /* getLvaluereq - get the last lvalreq level */
3934 /*-----------------------------------------------------------------*/
3935 int getLvaluereqLvl()
3938 lpItem = peekSet(lvaluereqSet);
3939 if(lpItem) return lpItem->lvl;
3942 /*-----------------------------------------------------------------*/
3943 /* isLvaluereq - is lvalreq valid for this level ? */
3944 /*-----------------------------------------------------------------*/
3945 int isLvaluereq(int lvl)
3948 lpItem = peekSet(lvaluereqSet);
3949 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3953 /*-----------------------------------------------------------------*/
3954 /* ast2iCode - creates an icodeList from an ast */
3955 /*-----------------------------------------------------------------*/
3957 ast2iCode (ast * tree,int lvl)
3959 operand *left = NULL;
3960 operand *right = NULL;
3964 /* set the global variables for filename & line number */
3966 filename = tree->filename;
3968 lineno = tree->lineno;
3970 block = tree->block;
3972 scopeLevel = tree->level;
3974 seqPoint = tree->seqPoint;
3976 if (tree->type == EX_VALUE)
3977 return operandFromValue (tree->opval.val);
3979 if (tree->type == EX_LINK)
3980 return operandFromLink (tree->opval.lnk);
3982 /* if we find a nullop */
3983 if (tree->type == EX_OP &&
3984 (tree->opval.op == NULLOP ||
3985 tree->opval.op == BLOCK))
3987 if (tree->left && tree->left->type == EX_VALUE)
3988 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3990 ast2iCode (tree->left,lvl+1);
3991 if (tree->right && tree->right->type == EX_VALUE)
3992 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3994 ast2iCode (tree->right,lvl+1);
3998 /* special cases for not evaluating */
3999 if (tree->opval.op != ':' &&
4000 tree->opval.op != '?' &&
4001 tree->opval.op != CALL &&
4002 tree->opval.op != IFX &&
4003 tree->opval.op != AND_OP &&
4004 tree->opval.op != OR_OP &&
4005 tree->opval.op != LABEL &&
4006 tree->opval.op != GOTO &&
4007 tree->opval.op != SWITCH &&
4008 tree->opval.op != FUNCTION &&
4009 tree->opval.op != INLINEASM &&
4010 tree->opval.op != CRITICAL)
4013 if (IS_ASSIGN_OP (tree->opval.op) ||
4014 IS_DEREF_OP (tree) ||
4015 (tree->opval.op == '&' && !tree->right) ||
4016 tree->opval.op == PTR_OP)
4019 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4020 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4023 left = operandFromAst (tree->left,lvl);
4025 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4026 left = geniCodeRValue (left, TRUE);
4030 left = operandFromAst (tree->left,lvl);
4032 if (tree->opval.op == INC_OP ||
4033 tree->opval.op == DEC_OP)
4036 right = operandFromAst (tree->right,lvl);
4041 right = operandFromAst (tree->right,lvl);
4045 /* now depending on the type of operand */
4046 /* this will be a biggy */
4047 switch (tree->opval.op)
4050 case '[': /* array operation */
4052 //sym_link *ltype = operandType (left);
4053 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4054 left = geniCodeRValue (left, FALSE);
4055 right = geniCodeRValue (right, TRUE);
4058 return geniCodeArray (left, right,lvl);
4060 case '.': /* structure dereference */
4061 if (IS_PTR (operandType (left)))
4062 left = geniCodeRValue (left, TRUE);
4064 left = geniCodeRValue (left, FALSE);
4066 return geniCodeStruct (left, right, tree->lvalue);
4068 case PTR_OP: /* structure pointer dereference */
4071 pType = operandType (left);
4072 left = geniCodeRValue (left, TRUE);
4074 setOClass (pType, getSpec (operandType (left)));
4077 return geniCodeStruct (left, right, tree->lvalue);
4079 case INC_OP: /* increment operator */
4081 return geniCodePostInc (left);
4083 return geniCodePreInc (right, tree->lvalue);
4085 case DEC_OP: /* decrement operator */
4087 return geniCodePostDec (left);
4089 return geniCodePreDec (right, tree->lvalue);
4091 case '&': /* bitwise and or address of operator */
4093 { /* this is a bitwise operator */
4094 left = geniCodeRValue (left, FALSE);
4095 right = geniCodeRValue (right, FALSE);
4096 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4099 return geniCodeAddressOf (left);
4101 case '|': /* bitwise or & xor */
4103 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4104 geniCodeRValue (right, FALSE),
4109 return geniCodeDivision (geniCodeRValue (left, FALSE),
4110 geniCodeRValue (right, FALSE),
4111 getResultTypeFromType (tree->ftype));
4114 return geniCodeModulus (geniCodeRValue (left, FALSE),
4115 geniCodeRValue (right, FALSE),
4116 getResultTypeFromType (tree->ftype));
4119 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4120 geniCodeRValue (right, FALSE),
4121 getResultTypeFromType (tree->ftype));
4123 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4127 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4128 geniCodeRValue (right, FALSE),
4129 getResultTypeFromType (tree->ftype));
4131 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4135 return geniCodeAdd (geniCodeRValue (left, FALSE),
4136 geniCodeRValue (right, FALSE),
4137 getResultTypeFromType (tree->ftype),
4140 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4143 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4144 geniCodeRValue (right, FALSE),
4145 getResultTypeFromType (tree->ftype));
4148 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4149 geniCodeRValue (right, FALSE));
4151 #if 0 // this indeed needs a second thought
4155 // let's keep this simple: get the rvalue we need
4156 op=geniCodeRValue (right, FALSE);
4157 // now cast it to whatever we want
4158 op=geniCodeCast (operandType(left), op, FALSE);
4159 // if this is going to be used as an lvalue, make it so
4165 #else // bug #604575, is it a bug ????
4166 return geniCodeCast (operandType (left),
4167 geniCodeRValue (right, FALSE), FALSE);
4174 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4179 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4180 setOperandType (op, UCHARTYPE);
4185 return geniCodeLogicAndOr (tree, lvl);
4192 /* different compilers (even different gccs) evaluate
4193 the two calls in a different order. to get the same
4194 result on all machines we've to specify a clear sequence.
4195 return geniCodeLogic (geniCodeRValue (left, FALSE),
4196 geniCodeRValue (right, FALSE),
4200 operand *leftOp, *rightOp;
4202 leftOp = geniCodeRValue (left , FALSE);
4203 rightOp = geniCodeRValue (right, FALSE);
4205 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4208 return geniCodeConditional (tree,lvl);
4211 return operandFromLit (getSize (tree->right->ftype));
4215 sym_link *rtype = operandType (right);
4216 sym_link *ltype = operandType (left);
4217 if (IS_PTR (rtype) && IS_ITEMP (right)
4218 && right->isaddr && compareType (rtype->next, ltype) == 1)
4219 right = geniCodeRValue (right, TRUE);
4221 right = geniCodeRValue (right, FALSE);
4223 geniCodeAssign (left, right, 0, 1);
4228 geniCodeAssign (left,
4229 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4231 geniCodeRValue (right, FALSE),
4232 getResultTypeFromType (tree->ftype)),
4237 geniCodeAssign (left,
4238 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4240 geniCodeRValue (right, FALSE),
4241 getResultTypeFromType (tree->ftype)),
4245 geniCodeAssign (left,
4246 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4248 geniCodeRValue (right, FALSE),
4249 getResultTypeFromType (tree->ftype)),
4253 sym_link *rtype = operandType (right);
4254 sym_link *ltype = operandType (left);
4255 if (IS_PTR (rtype) && IS_ITEMP (right)
4256 && right->isaddr && compareType (rtype->next, ltype) == 1)
4257 right = geniCodeRValue (right, TRUE);
4259 right = geniCodeRValue (right, FALSE);
4262 return geniCodeAssign (left,
4263 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4266 getResultTypeFromType (tree->ftype),
4272 sym_link *rtype = operandType (right);
4273 sym_link *ltype = operandType (left);
4274 if (IS_PTR (rtype) && IS_ITEMP (right)
4275 && right->isaddr && compareType (rtype->next, ltype) == 1)
4277 right = geniCodeRValue (right, TRUE);
4281 right = geniCodeRValue (right, FALSE);
4284 geniCodeAssign (left,
4285 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4288 getResultTypeFromType (tree->ftype)),
4293 geniCodeAssign (left,
4294 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4296 geniCodeRValue (right, FALSE),
4297 getResultTypeFromType (tree->ftype)),
4301 geniCodeAssign (left,
4302 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4304 geniCodeRValue (right, FALSE)), 0, 1);
4307 geniCodeAssign (left,
4308 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4310 geniCodeRValue (right, FALSE),
4312 operandType (left)), 0, 1);
4315 geniCodeAssign (left,
4316 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4318 geniCodeRValue (right, FALSE),
4320 operandType (left)), 0, 1);
4323 geniCodeAssign (left,
4324 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4326 geniCodeRValue (right, FALSE),
4328 operandType (left)), 0, 1);
4330 return geniCodeRValue (right, FALSE);
4333 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4336 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4337 return ast2iCode (tree->right,lvl+1);
4340 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4341 return ast2iCode (tree->right,lvl+1);
4344 geniCodeFunctionBody (tree,lvl);
4348 geniCodeReturn (right);
4352 geniCodeIfx (tree,lvl);
4356 geniCodeSwitch (tree,lvl);
4360 geniCodeInline (tree);
4364 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4368 geniCodeCritical (tree, lvl);
4374 /*-----------------------------------------------------------------*/
4375 /* reverseICChain - gets from the list and creates a linkedlist */
4376 /*-----------------------------------------------------------------*/
4383 while ((loop = getSet (&iCodeChain)))
4395 /*-----------------------------------------------------------------*/
4396 /* iCodeFromAst - given an ast will convert it to iCode */
4397 /*-----------------------------------------------------------------*/
4399 iCodeFromAst (ast * tree)
4401 returnLabel = newiTempLabel ("_return");
4402 entryLabel = newiTempLabel ("_entry");
4404 return reverseiCChain ();
4407 static const char *opTypeToStr(OPTYPE op)
4411 case SYMBOL: return "symbol";
4412 case VALUE: return "value";
4413 case TYPE: return "type";
4415 return "undefined type";
4419 operand *validateOpType(operand *op,
4426 if (op && op->type == type)
4431 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4432 " expected %s, got %s\n",
4433 macro, args, file, line,
4434 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4436 return op; // never reached, makes compiler happy.