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 if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
238 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}" , */
239 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
241 OP_LIVEFROM (op), OP_LIVETO (op),
242 OP_SYMBOL (op)->stack,
243 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
244 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
245 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
249 printTypeChain (operandType (op), file);
250 if (SPIL_LOC (op) && IS_ITEMP (op))
251 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
256 /* if assigned to registers */
257 if (OP_SYMBOL (op)->nRegs)
259 if (OP_SYMBOL (op)->isspilt)
261 if (!OP_SYMBOL (op)->remat)
262 if (OP_SYMBOL (op)->usl.spillLoc)
263 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
264 OP_SYMBOL (op)->usl.spillLoc->rname :
265 OP_SYMBOL (op)->usl.spillLoc->name));
267 fprintf (file, "[err]");
269 fprintf (file, "[remat]");
275 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
276 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 //#else /* } else { */
282 /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
283 fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
285 if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
287 fprintf (file, "[lr%d:%d so:%d]",
288 OP_LIVEFROM (op), OP_LIVETO (op),
289 OP_SYMBOL (op)->stack);
292 if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
295 printTypeChain (operandType (op), file);
296 if (SPIL_LOC (op) && IS_ITEMP (op))
297 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
301 /* if assigned to registers */
302 if (OP_SYMBOL (op)->nRegs)
304 if (OP_SYMBOL (op)->isspilt)
306 if (!OP_SYMBOL (op)->remat)
307 if (OP_SYMBOL (op)->usl.spillLoc)
308 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
309 OP_SYMBOL (op)->usl.spillLoc->rname :
310 OP_SYMBOL (op)->usl.spillLoc->name));
312 fprintf (file, "[err]");
314 fprintf (file, "[remat]");
320 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
321 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 (compareType (left->operand.valOperand->type,
1432 right->operand.valOperand->type) &&
1433 (floatFromVal (left->operand.valOperand) ==
1434 floatFromVal (right->operand.valOperand)));
1436 if (compareType (left->operand.typeOperand,
1437 right->operand.typeOperand) == 1)
1444 /*-------------------------------------------------------------------*/
1445 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1446 /*-------------------------------------------------------------------*/
1448 isiCodeEqual (iCode * left, iCode * right)
1450 /* if the same pointer */
1454 /* if either of them null */
1455 if (!left || !right)
1458 /* if operand are the same */
1459 if (left->op == right->op)
1462 /* compare all the elements depending on type */
1463 if (left->op != IFX)
1465 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1467 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1473 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1475 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1477 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1486 /*-----------------------------------------------------------------*/
1487 /* newiTempFromOp - create a temp Operand with same attributes */
1488 /*-----------------------------------------------------------------*/
1490 newiTempFromOp (operand * op)
1500 nop = newiTempOperand (operandType (op), TRUE);
1501 nop->isaddr = op->isaddr;
1502 nop->isvolatile = op->isvolatile;
1503 nop->isGlobal = op->isGlobal;
1504 nop->isLiteral = op->isLiteral;
1505 nop->usesDefs = op->usesDefs;
1506 nop->isParm = op->isParm;
1510 /*-----------------------------------------------------------------*/
1511 /* operand from operand - creates an operand holder for the type */
1512 /*-----------------------------------------------------------------*/
1514 operandFromOperand (operand * op)
1520 nop = newOperand ();
1521 nop->type = op->type;
1522 nop->isaddr = op->isaddr;
1524 nop->isvolatile = op->isvolatile;
1525 nop->isGlobal = op->isGlobal;
1526 nop->isLiteral = op->isLiteral;
1527 nop->usesDefs = op->usesDefs;
1528 nop->isParm = op->isParm;
1533 nop->operand.symOperand = op->operand.symOperand;
1536 nop->operand.valOperand = op->operand.valOperand;
1539 nop->operand.typeOperand = op->operand.typeOperand;
1546 /*-----------------------------------------------------------------*/
1547 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1548 /*-----------------------------------------------------------------*/
1550 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1552 operand *nop = operandFromOperand (op);
1554 if (nop->type == SYMBOL)
1556 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1557 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1563 /*-----------------------------------------------------------------*/
1564 /* operandFromSymbol - creates an operand from a symbol */
1565 /*-----------------------------------------------------------------*/
1567 operandFromSymbol (symbol * sym)
1572 /* if the symbol's type is a literal */
1573 /* then it is an enumerator type */
1574 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1575 return operandFromValue (valFromType (sym->etype));
1578 sym->key = ++operandKey;
1580 /* if this an implicit variable, means struct/union */
1581 /* member so just return it */
1582 if (sym->implicit || IS_FUNC (sym->type))
1586 op->operand.symOperand = sym;
1588 op->isvolatile = isOperandVolatile (op, TRUE);
1589 op->isGlobal = isOperandGlobal (op);
1593 /* under the following conditions create a
1594 register equivalent for a local symbol */
1595 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1596 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1598 (!(options.model == MODEL_FLAT24)) ) &&
1599 options.stackAuto == 0)
1602 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1603 !IS_FUNC (sym->type) && /* not a function */
1604 !sym->_isparm && /* not a parameter */
1605 IS_AUTO (sym) && /* is a local auto variable */
1606 !sym->addrtaken && /* whose address has not been taken */
1607 !sym->reqv && /* does not already have a reg equivalence */
1608 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1609 !sym->islbl && /* not a label */
1610 ok && /* farspace check */
1611 !IS_BITVAR (sym->etype) /* not a bit variable */
1615 /* we will use it after all optimizations
1616 and before liveRange calculation */
1617 sym->reqv = newiTempOperand (sym->type, 0);
1618 sym->reqv->key = sym->key;
1619 OP_SYMBOL (sym->reqv)->prereqv = sym;
1620 OP_SYMBOL (sym->reqv)->key = sym->key;
1621 OP_SYMBOL (sym->reqv)->isreqv = 1;
1622 OP_SYMBOL (sym->reqv)->islocal = 1;
1623 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1624 SPIL_LOC (sym->reqv) = sym;
1627 if (!IS_AGGREGATE (sym->type))
1631 op->operand.symOperand = sym;
1634 op->isvolatile = isOperandVolatile (op, TRUE);
1635 op->isGlobal = isOperandGlobal (op);
1636 op->isPtr = IS_PTR (operandType (op));
1637 op->isParm = sym->_isparm;
1642 /* itemp = &[_symbol] */
1644 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1645 IC_LEFT (ic)->type = SYMBOL;
1646 IC_LEFT (ic)->operand.symOperand = sym;
1647 IC_LEFT (ic)->key = sym->key;
1648 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1649 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1650 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1653 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1654 if (IS_ARRAY (sym->type))
1656 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1657 IC_RESULT (ic)->isaddr = 0;
1660 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1664 return IC_RESULT (ic);
1667 /*-----------------------------------------------------------------*/
1668 /* operandFromValue - creates an operand from value */
1669 /*-----------------------------------------------------------------*/
1671 operandFromValue (value * val)
1675 /* if this is a symbol then do the symbol thing */
1677 return operandFromSymbol (val->sym);
1679 /* this is not a symbol */
1682 op->operand.valOperand = val;
1683 op->isLiteral = isOperandLiteral (op);
1687 /*-----------------------------------------------------------------*/
1688 /* operandFromLink - operand from typeChain */
1689 /*-----------------------------------------------------------------*/
1691 operandFromLink (sym_link * type)
1695 /* operand from sym_link */
1701 op->operand.typeOperand = copyLinkChain (type);
1705 /*-----------------------------------------------------------------*/
1706 /* operandFromLit - makes an operand from a literal value */
1707 /*-----------------------------------------------------------------*/
1709 operandFromLit (double i)
1711 return operandFromValue (valueFromLit (i));
1714 /*-----------------------------------------------------------------*/
1715 /* operandFromAst - creates an operand from an ast */
1716 /*-----------------------------------------------------------------*/
1718 operandFromAst (ast * tree,int lvl)
1724 /* depending on type do */
1728 return ast2iCode (tree,lvl+1);
1732 return operandFromValue (tree->opval.val);
1736 return operandFromLink (tree->opval.lnk);
1743 /* Just to keep the compiler happy */
1744 return (operand *) 0;
1747 /*-----------------------------------------------------------------*/
1748 /* setOperandType - sets the operand's type to the given type */
1749 /*-----------------------------------------------------------------*/
1751 setOperandType (operand * op, sym_link * type)
1753 /* depending on the type of operand */
1758 op->operand.valOperand->etype =
1759 getSpec (op->operand.valOperand->type =
1760 copyLinkChain (type));
1764 if (op->operand.symOperand->isitmp)
1765 op->operand.symOperand->etype =
1766 getSpec (op->operand.symOperand->type =
1767 copyLinkChain (type));
1769 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1770 "attempt to modify type of source");
1774 op->operand.typeOperand = copyLinkChain (type);
1780 /*-----------------------------------------------------------------*/
1781 /* Get size in byte of ptr need to access an array */
1782 /*-----------------------------------------------------------------*/
1784 getArraySizePtr (operand * op)
1786 sym_link *ltype = operandType(op);
1790 int size = getSize(ltype);
1791 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1796 sym_link *letype = getSpec(ltype);
1797 switch (PTR_TYPE (SPEC_OCLS (letype)))
1809 if (GPTRSIZE > FPTRSIZE)
1810 return (GPTRSIZE-1);
1821 /*-----------------------------------------------------------------*/
1822 /* perform "usual unary conversions" */
1823 /*-----------------------------------------------------------------*/
1826 usualUnaryConversions (operand * op)
1828 if (IS_INTEGRAL (operandType (op)))
1830 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1833 return geniCodeCast (INTTYPE, op, TRUE);
1840 /*-----------------------------------------------------------------*/
1841 /* perform "usual binary conversions" */
1842 /*-----------------------------------------------------------------*/
1845 usualBinaryConversions (operand ** op1, operand ** op2,
1846 RESULT_TYPE resultType, int op)
1849 sym_link *rtype = operandType (*op2);
1850 sym_link *ltype = operandType (*op1);
1852 ctype = computeType (ltype, rtype, resultType, op);
1859 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1861 /* one byte operations: keep signedness for code generator */
1869 *op1 = geniCodeCast (ctype, *op1, TRUE);
1870 *op2 = geniCodeCast (ctype, *op2, TRUE);
1875 /*-----------------------------------------------------------------*/
1876 /* geniCodeValueAtAddress - generate intermeditate code for value */
1878 /*-----------------------------------------------------------------*/
1880 geniCodeRValue (operand * op, bool force)
1883 sym_link *type = operandType (op);
1884 sym_link *etype = getSpec (type);
1886 /* if this is an array & already */
1887 /* an address then return this */
1888 if (IS_AGGREGATE (type) ||
1889 (IS_PTR (type) && !force && !op->isaddr))
1890 return operandFromOperand (op);
1892 /* if this is not an address then must be */
1893 /* rvalue already so return this one */
1897 /* if this is not a temp symbol then */
1898 if (!IS_ITEMP (op) &&
1900 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1902 op = operandFromOperand (op);
1907 if (IS_SPEC (type) &&
1908 IS_TRUE_SYMOP (op) &&
1909 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1910 (options.model == MODEL_FLAT24) ))
1912 op = operandFromOperand (op);
1917 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1918 if (IS_PTR (type) && op->isaddr && force)
1921 type = copyLinkChain (type);
1923 IC_RESULT (ic) = newiTempOperand (type, 1);
1924 IC_RESULT (ic)->isaddr = 0;
1926 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1930 return IC_RESULT (ic);
1933 /*-----------------------------------------------------------------*/
1934 /* geniCodeCast - changes the value from one type to another */
1935 /*-----------------------------------------------------------------*/
1937 geniCodeCast (sym_link * type, operand * op, bool implicit)
1941 sym_link *opetype = getSpec (optype = operandType (op));
1945 /* one of them has size zero then error */
1946 if (IS_VOID (optype))
1948 werror (E_CAST_ZERO);
1952 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1954 geniCodeArray2Ptr (op);
1958 /* if the operand is already the desired type then do nothing */
1959 if (compareType (type, optype) == 1)
1962 /* if this is a literal then just change the type & return */
1963 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1965 return operandFromValue (valCastLiteral (type,
1966 operandLitValue (op)));
1969 /* if casting to/from pointers, do some checking */
1970 if (IS_PTR(type)) { // to a pointer
1971 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1972 if (IS_INTEGRAL(optype)) {
1973 // maybe this is NULL, than it's ok.
1974 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1975 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1976 // no way to set the storage
1977 if (IS_LITERAL(optype)) {
1978 werror(E_LITERAL_GENERIC);
1981 werror(E_NONPTR2_GENPTR);
1984 } else if (implicit) {
1985 werror(W_INTEGRAL2PTR_NOCAST);
1990 // shouldn't do that with float, array or structure unless to void
1991 if (!IS_VOID(getSpec(type)) &&
1992 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1993 werror(E_INCOMPAT_TYPES);
1997 } else { // from a pointer to a pointer
1998 if (IS_GENPTR(type) && IS_VOID(type->next))
1999 { // cast to void* is always allowed
2001 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2002 { // cast from void* is always allowed
2004 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2005 // if not a pointer to a function
2006 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2007 if (implicit) { // if not to generic, they have to match
2008 if (!IS_GENPTR(type) &&
2009 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2010 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2014 werror(E_INCOMPAT_PTYPES);
2021 } else { // to a non pointer
2022 if (IS_PTR(optype)) { // from a pointer
2023 if (implicit) { // sneaky
2024 if (IS_INTEGRAL(type)) {
2025 werror(W_PTR2INTEGRAL_NOCAST);
2027 } else { // shouldn't do that with float, array or structure
2028 werror(E_INCOMPAT_TYPES);
2035 printFromToType (optype, type);
2038 /* if they are the same size create an assignment */
2040 /* This seems very dangerous to me, since there are several */
2041 /* optimizations (for example, gcse) that don't notice the */
2042 /* cast hidden in this assignement and may simplify an */
2043 /* iCode to use the original (uncasted) operand. */
2044 /* Unfortunately, other things break when this cast is */
2045 /* made explicit. Need to fix this someday. */
2046 /* -- EEP, 2004/01/21 */
2047 if (getSize (type) == getSize (optype) &&
2048 !IS_BITFIELD (type) &&
2050 !IS_FLOAT (optype) &&
2051 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2052 (!IS_SPEC (type) && !IS_SPEC (optype))))
2054 ic = newiCode ('=', NULL, op);
2055 IC_RESULT (ic) = newiTempOperand (type, 0);
2056 SPIL_LOC (IC_RESULT (ic)) =
2057 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2058 IC_RESULT (ic)->isaddr = 0;
2062 ic = newiCode (CAST, operandFromLink (type),
2063 geniCodeRValue (op, FALSE));
2065 IC_RESULT (ic) = newiTempOperand (type, 0);
2068 /* preserve the storage class & output class */
2069 /* of the original variable */
2070 restype = getSpec (operandType (IC_RESULT (ic)));
2071 if (!IS_LITERAL(opetype) &&
2074 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2075 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2078 return IC_RESULT (ic);
2081 /*-----------------------------------------------------------------*/
2082 /* geniCodeLabel - will create a Label */
2083 /*-----------------------------------------------------------------*/
2085 geniCodeLabel (symbol * label)
2089 ic = newiCodeLabelGoto (LABEL, label);
2093 /*-----------------------------------------------------------------*/
2094 /* geniCodeGoto - will create a Goto */
2095 /*-----------------------------------------------------------------*/
2097 geniCodeGoto (symbol * label)
2101 ic = newiCodeLabelGoto (GOTO, label);
2105 /*-----------------------------------------------------------------*/
2106 /* geniCodeMultiply - gen intermediate code for multiplication */
2107 /*-----------------------------------------------------------------*/
2109 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2116 /* if they are both literal then we know the result */
2117 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2118 return operandFromValue (valMult (left->operand.valOperand,
2119 right->operand.valOperand));
2121 if (IS_LITERAL(retype)) {
2122 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2125 resType = usualBinaryConversions (&left, &right, resultType, '*');
2127 rtype = operandType (right);
2128 retype = getSpec (rtype);
2129 ltype = operandType (left);
2130 letype = getSpec (ltype);
2133 /* if the right is a literal & power of 2 */
2134 /* then make it a left shift */
2135 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2136 efficient in most cases than 2 bytes result = 2 bytes << literal
2137 if port has 1 byte muldiv */
2138 if (p2 && !IS_FLOAT (letype)
2139 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2140 && (port->support.muldiv == 1))
2141 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2142 && strcmp (port->target, "pic14") != 0)
2144 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2146 /* LEFT_OP need same size for left and result, */
2147 left = geniCodeCast (resType, left, TRUE);
2148 ltype = operandType (left);
2150 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2154 ic = newiCode ('*', left, right); /* normal multiplication */
2155 /* if the size left or right > 1 then support routine */
2156 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2160 IC_RESULT (ic) = newiTempOperand (resType, 1);
2163 return IC_RESULT (ic);
2166 /*-----------------------------------------------------------------*/
2167 /* geniCodeDivision - gen intermediate code for division */
2168 /*-----------------------------------------------------------------*/
2170 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2175 sym_link *rtype = operandType (right);
2176 sym_link *retype = getSpec (rtype);
2177 sym_link *ltype = operandType (left);
2178 sym_link *letype = getSpec (ltype);
2180 resType = usualBinaryConversions (&left, &right, resultType, '/');
2182 /* if the right is a literal & power of 2
2183 and left is unsigned then make it a
2185 if (IS_LITERAL (retype) &&
2186 !IS_FLOAT (letype) &&
2187 IS_UNSIGNED(letype) &&
2188 (p2 = powof2 ((TYPE_UDWORD)
2189 floatFromVal (right->operand.valOperand)))) {
2190 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2194 ic = newiCode ('/', left, right); /* normal division */
2195 /* if the size left or right > 1 then support routine */
2196 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2199 IC_RESULT (ic) = newiTempOperand (resType, 0);
2202 return IC_RESULT (ic);
2204 /*-----------------------------------------------------------------*/
2205 /* geniCodeModulus - gen intermediate code for modulus */
2206 /*-----------------------------------------------------------------*/
2208 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2214 /* if they are both literal then we know the result */
2215 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2216 return operandFromValue (valMod (left->operand.valOperand,
2217 right->operand.valOperand));
2219 resType = usualBinaryConversions (&left, &right, resultType, '%');
2221 /* now they are the same size */
2222 ic = newiCode ('%', left, right);
2224 /* if the size left or right > 1 then support routine */
2225 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2227 IC_RESULT (ic) = newiTempOperand (resType, 0);
2230 return IC_RESULT (ic);
2233 /*-----------------------------------------------------------------*/
2234 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2235 /*-----------------------------------------------------------------*/
2237 geniCodePtrPtrSubtract (operand * left, operand * right)
2243 /* if they are both literals then */
2244 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2246 result = operandFromValue (valMinus (left->operand.valOperand,
2247 right->operand.valOperand));
2251 ic = newiCode ('-', left, right);
2253 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2257 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2261 // should we really do this? is this ANSI?
2262 return geniCodeDivision (result,
2263 operandFromLit (getSize (ltype->next)),
2267 /*-----------------------------------------------------------------*/
2268 /* geniCodeSubtract - generates code for subtraction */
2269 /*-----------------------------------------------------------------*/
2271 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2278 /* if they both pointers then */
2279 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2280 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2281 return geniCodePtrPtrSubtract (left, right);
2283 /* if they are both literal then we know the result */
2284 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2285 && left->isLiteral && right->isLiteral)
2286 return operandFromValue (valMinus (left->operand.valOperand,
2287 right->operand.valOperand));
2289 /* if left is an array or pointer */
2290 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2292 isarray = left->isaddr;
2293 right = geniCodeMultiply (right,
2294 operandFromLit (getSize (ltype->next)),
2295 (getArraySizePtr(left) >= INTSIZE) ?
2298 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2301 { /* make them the same size */
2302 resType = usualBinaryConversions (&left, &right, resultType, '-');
2305 ic = newiCode ('-', left, right);
2307 IC_RESULT (ic) = newiTempOperand (resType, 1);
2308 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2310 /* if left or right is a float */
2311 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2315 return IC_RESULT (ic);
2318 /*-----------------------------------------------------------------*/
2319 /* geniCodeAdd - generates iCode for addition */
2320 /*-----------------------------------------------------------------*/
2322 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2331 /* if the right side is LITERAL zero */
2332 /* return the left side */
2333 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2336 /* if left is literal zero return right */
2337 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2340 /* if left is a pointer then size */
2341 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2343 isarray = left->isaddr;
2344 // there is no need to multiply with 1
2345 if (getSize (ltype->next) != 1)
2347 size = operandFromLit (getSize (ltype->next));
2348 SPEC_USIGN (getSpec (operandType (size))) = 1;
2349 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2350 right = geniCodeMultiply (right,
2352 (getArraySizePtr(left) >= INTSIZE) ?
2355 /* Even if right is a 'unsigned char',
2356 the result will be a 'signed int' due to the promotion rules.
2357 It doesn't make sense when accessing arrays, so let's fix it here: */
2359 SPEC_USIGN (getSpec (operandType (right))) = 1;
2361 resType = copyLinkChain (ltype);
2364 { // make them the same size
2365 resType = usualBinaryConversions (&left, &right, resultType, '+');
2368 /* if they are both literals then we know */
2369 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2370 && left->isLiteral && right->isLiteral)
2371 return operandFromValue (valPlus (valFromType (ltype),
2372 valFromType (rtype)));
2374 ic = newiCode ('+', left, right);
2376 IC_RESULT (ic) = newiTempOperand (resType, 1);
2377 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2379 /* if left or right is a float then support
2381 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2386 return IC_RESULT (ic);
2390 /*-----------------------------------------------------------------*/
2391 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2392 /*-----------------------------------------------------------------*/
2394 aggrToPtr (sym_link * type, bool force)
2399 if (IS_PTR (type) && !force)
2402 etype = getSpec (type);
2403 ptype = newLink (DECLARATOR);
2407 /* set the pointer depending on the storage class */
2408 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2412 /*------------------------------------------------------------------*/
2413 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2414 /*------------------------------------------------------------------*/
2416 aggrToPtrDclType (sym_link * type, bool force)
2418 if (IS_PTR (type) && !force)
2419 return DCL_TYPE (type);
2421 /* return the pointer depending on the storage class */
2422 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2425 /*-----------------------------------------------------------------*/
2426 /* geniCodeArray2Ptr - array to pointer */
2427 /*-----------------------------------------------------------------*/
2429 geniCodeArray2Ptr (operand * op)
2431 sym_link *optype = operandType (op);
2432 sym_link *opetype = getSpec (optype);
2434 /* set the pointer depending on the storage class */
2435 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2442 /*-----------------------------------------------------------------*/
2443 /* geniCodeArray - array access */
2444 /*-----------------------------------------------------------------*/
2446 geniCodeArray (operand * left, operand * right, int lvl)
2450 sym_link *ltype = operandType (left);
2455 if (IS_PTR (ltype->next) && left->isaddr)
2457 left = geniCodeRValue (left, FALSE);
2460 return geniCodeDerefPtr (geniCodeAdd (left,
2462 (getArraySizePtr(left) >= INTSIZE) ?
2468 size = operandFromLit (getSize (ltype->next));
2469 SPEC_USIGN (getSpec (operandType (size))) = 1;
2470 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2471 right = geniCodeMultiply (right,
2473 (getArraySizePtr(left) >= INTSIZE) ?
2476 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2477 It doesn't make sense when accessing arrays, so let's fix it here: */
2479 SPEC_USIGN (getSpec (operandType (right))) = 1;
2480 /* we can check for limits here */
2481 /* already done in SDCCast.c
2482 if (isOperandLiteral (right) &&
2485 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2487 werror (W_IDX_OUT_OF_BOUNDS,
2488 (int) operandLitValue (right) / getSize (ltype->next),
2493 ic = newiCode ('+', left, right);
2495 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2496 !IS_AGGREGATE (ltype->next) &&
2497 !IS_PTR (ltype->next))
2498 ? ltype : ltype->next), 0);
2500 if (!IS_AGGREGATE (ltype->next))
2502 IC_RESULT (ic)->isaddr = 1;
2503 IC_RESULT (ic)->aggr2ptr = 1;
2507 return IC_RESULT (ic);
2510 /*-----------------------------------------------------------------*/
2511 /* geniCodeStruct - generates intermediate code for structures */
2512 /*-----------------------------------------------------------------*/
2514 geniCodeStruct (operand * left, operand * right, bool islval)
2517 sym_link *type = operandType (left);
2518 sym_link *etype = getSpec (type);
2520 symbol *element = getStructElement (SPEC_STRUCT (etype),
2521 right->operand.symOperand);
2523 wassert(IS_SYMOP(right));
2525 /* add the offset */
2526 ic = newiCode ('+', left, operandFromLit (element->offset));
2528 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2530 /* preserve the storage & output class of the struct */
2531 /* as well as the volatile attribute */
2532 retype = getSpec (operandType (IC_RESULT (ic)));
2533 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2534 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2535 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2536 SPEC_CONST (retype) |= SPEC_CONST (etype);
2538 if (IS_PTR (element->type))
2539 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2541 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2544 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2547 /*-----------------------------------------------------------------*/
2548 /* geniCodePostInc - generate int code for Post increment */
2549 /*-----------------------------------------------------------------*/
2551 geniCodePostInc (operand * op)
2555 sym_link *optype = operandType (op);
2557 operand *rv = (IS_ITEMP (op) ?
2558 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2560 sym_link *rvtype = operandType (rv);
2563 /* if this is not an address we have trouble */
2566 werror (E_LVALUE_REQUIRED, "++");
2570 rOp = newiTempOperand (rvtype, 0);
2571 OP_SYMBOL(rOp)->noSpilLoc = 1;
2574 OP_SYMBOL(rv)->noSpilLoc = 1;
2576 geniCodeAssign (rOp, rv, 0, 0);
2578 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2580 werror(W_SIZEOF_VOID);
2581 if (IS_FLOAT (rvtype))
2582 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2584 ic = newiCode ('+', rv, operandFromLit (size));
2586 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2589 geniCodeAssign (op, result, 0, 0);
2595 /*-----------------------------------------------------------------*/
2596 /* geniCodePreInc - generate code for preIncrement */
2597 /*-----------------------------------------------------------------*/
2599 geniCodePreInc (operand * op, bool lvalue)
2602 sym_link *optype = operandType (op);
2603 operand *rop = (IS_ITEMP (op) ?
2604 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2606 sym_link *roptype = operandType (rop);
2612 werror (E_LVALUE_REQUIRED, "++");
2616 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2618 werror(W_SIZEOF_VOID);
2619 if (IS_FLOAT (roptype))
2620 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2622 ic = newiCode ('+', rop, operandFromLit (size));
2623 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2626 (void) geniCodeAssign (op, result, 0, 0);
2627 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2633 /*-----------------------------------------------------------------*/
2634 /* geniCodePostDec - generates code for Post decrement */
2635 /*-----------------------------------------------------------------*/
2637 geniCodePostDec (operand * op)
2641 sym_link *optype = operandType (op);
2643 operand *rv = (IS_ITEMP (op) ?
2644 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2646 sym_link *rvtype = operandType (rv);
2649 /* if this is not an address we have trouble */
2652 werror (E_LVALUE_REQUIRED, "--");
2656 rOp = newiTempOperand (rvtype, 0);
2657 OP_SYMBOL(rOp)->noSpilLoc = 1;
2660 OP_SYMBOL(rv)->noSpilLoc = 1;
2662 geniCodeAssign (rOp, rv, 0, 0);
2664 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2666 werror(W_SIZEOF_VOID);
2667 if (IS_FLOAT (rvtype))
2668 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2670 ic = newiCode ('-', rv, operandFromLit (size));
2672 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2675 geniCodeAssign (op, result, 0, 0);
2681 /*-----------------------------------------------------------------*/
2682 /* geniCodePreDec - generate code for pre decrement */
2683 /*-----------------------------------------------------------------*/
2685 geniCodePreDec (operand * op, bool lvalue)
2688 sym_link *optype = operandType (op);
2689 operand *rop = (IS_ITEMP (op) ?
2690 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2692 sym_link *roptype = operandType (rop);
2698 werror (E_LVALUE_REQUIRED, "--");
2702 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2704 werror(W_SIZEOF_VOID);
2705 if (IS_FLOAT (roptype))
2706 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2708 ic = newiCode ('-', rop, operandFromLit (size));
2709 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2712 (void) geniCodeAssign (op, result, 0, 0);
2713 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2720 /*-----------------------------------------------------------------*/
2721 /* geniCodeBitwise - gen int code for bitWise operators */
2722 /*-----------------------------------------------------------------*/
2724 geniCodeBitwise (operand * left, operand * right,
2725 int oper, sym_link * resType)
2729 left = geniCodeCast (resType, left, TRUE);
2730 right = geniCodeCast (resType, right, TRUE);
2732 ic = newiCode (oper, left, right);
2733 IC_RESULT (ic) = newiTempOperand (resType, 0);
2736 return IC_RESULT (ic);
2739 /*-----------------------------------------------------------------*/
2740 /* geniCodeAddressOf - gens icode for '&' address of operator */
2741 /*-----------------------------------------------------------------*/
2743 geniCodeAddressOf (operand * op)
2747 sym_link *optype = operandType (op);
2748 sym_link *opetype = getSpec (optype);
2750 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2752 op = operandFromOperand (op);
2757 /* lvalue check already done in decorateType */
2758 /* this must be a lvalue */
2759 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2760 /* werror (E_LVALUE_REQUIRED,"&"); */
2764 p = newLink (DECLARATOR);
2766 /* set the pointer depending on the storage class */
2767 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2769 p->next = copyLinkChain (optype);
2771 /* if already a temp */
2774 setOperandType (op, p);
2779 /* other wise make this of the type coming in */
2780 ic = newiCode (ADDRESS_OF, op, NULL);
2781 IC_RESULT (ic) = newiTempOperand (p, 1);
2782 IC_RESULT (ic)->isaddr = 0;
2784 return IC_RESULT (ic);
2786 /*-----------------------------------------------------------------*/
2787 /* setOClass - sets the output class depending on the pointer type */
2788 /*-----------------------------------------------------------------*/
2790 setOClass (sym_link * ptr, sym_link * spec)
2792 switch (DCL_TYPE (ptr))
2795 SPEC_OCLS (spec) = data;
2799 SPEC_OCLS (spec) = generic;
2803 SPEC_OCLS (spec) = xdata;
2807 SPEC_OCLS (spec) = code;
2811 SPEC_OCLS (spec) = idata;
2815 SPEC_OCLS (spec) = xstack;
2819 SPEC_OCLS (spec) = eeprom;
2828 /*-----------------------------------------------------------------*/
2829 /* geniCodeDerefPtr - dereference pointer with '*' */
2830 /*-----------------------------------------------------------------*/
2832 geniCodeDerefPtr (operand * op,int lvl)
2834 sym_link *rtype, *retype;
2835 sym_link *optype = operandType (op);
2837 // if this is an array then array access
2838 if (IS_ARRAY (optype)) {
2839 // don't worry, this will be optimized out later
2840 return geniCodeArray (op, operandFromLit (0), lvl);
2843 // just in case someone screws up
2844 wassert (IS_PTR (optype));
2846 if (IS_TRUE_SYMOP (op))
2849 op = geniCodeRValue (op, TRUE);
2852 /* now get rid of the pointer part */
2853 if (isLvaluereq(lvl) && IS_ITEMP (op))
2855 retype = getSpec (rtype = copyLinkChain (optype));
2859 retype = getSpec (rtype = copyLinkChain (optype->next));
2860 /* outputclass needs 2b updated */
2861 setOClass (optype, retype);
2864 op->isGptr = IS_GENPTR (optype);
2866 op->isaddr = (IS_PTR (rtype) ||
2867 IS_STRUCT (rtype) ||
2872 if (!isLvaluereq(lvl))
2873 op = geniCodeRValue (op, TRUE);
2875 setOperandType (op, rtype);
2880 /*-----------------------------------------------------------------*/
2881 /* geniCodeUnaryMinus - does a unary minus of the operand */
2882 /*-----------------------------------------------------------------*/
2884 geniCodeUnaryMinus (operand * op)
2887 sym_link *optype = operandType (op);
2889 if (IS_LITERAL (optype))
2890 return operandFromLit (-floatFromVal (op->operand.valOperand));
2892 ic = newiCode (UNARYMINUS, op, NULL);
2893 IC_RESULT (ic) = newiTempOperand (optype, 0);
2895 return IC_RESULT (ic);
2898 /*-----------------------------------------------------------------*/
2899 /* geniCodeLeftShift - gen i code for left shift */
2900 /*-----------------------------------------------------------------*/
2902 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2907 ic = newiCode (LEFT_OP, left, right);
2909 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2910 IC_RESULT (ic) = newiTempOperand (resType, 0);
2912 return IC_RESULT (ic);
2915 /*-----------------------------------------------------------------*/
2916 /* geniCodeRightShift - gen i code for right shift */
2917 /*-----------------------------------------------------------------*/
2919 geniCodeRightShift (operand * left, operand * right)
2923 ic = newiCode (RIGHT_OP, left, right);
2924 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2926 return IC_RESULT (ic);
2929 /*-----------------------------------------------------------------*/
2930 /* geniCodeLogic- logic code */
2931 /*-----------------------------------------------------------------*/
2933 geniCodeLogic (operand * left, operand * right, int op)
2937 sym_link *rtype = operandType (right);
2938 sym_link *ltype = operandType (left);
2940 /* left is integral type and right is literal then
2941 check if the literal value is within bounds */
2942 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2944 checkConstantRange(ltype,
2945 OP_VALUE(right), "compare operation", 1);
2948 /* if one operand is a pointer and the other is a literal generic void pointer,
2949 change the type of the literal generic void pointer to match the other pointer */
2950 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2951 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2953 /* find left's definition */
2954 ic = (iCode *) setFirstItem (iCodeChain);
2957 if (((ic->op == CAST) || (ic->op == '='))
2958 && isOperandEqual(left, IC_RESULT (ic)))
2961 ic = setNextItem (iCodeChain);
2963 /* if casting literal to generic pointer, then cast to rtype instead */
2964 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2966 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2967 ltype = operandType(left);
2970 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2971 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2973 /* find right's definition */
2974 ic = (iCode *) setFirstItem (iCodeChain);
2977 if (((ic->op == CAST) || (ic->op == '='))
2978 && isOperandEqual(right, IC_RESULT (ic)))
2981 ic = setNextItem (iCodeChain);
2983 /* if casting literal to generic pointer, then cast to rtype instead */
2984 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2986 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2987 rtype = operandType(right);
2991 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2993 ic = newiCode (op, left, right);
2994 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2996 /* if comparing float
2997 and not a '==' || '!=' || '&&' || '||' (these
2999 if (IS_FLOAT(ctype) &&
3007 return IC_RESULT (ic);
3010 /*-----------------------------------------------------------------*/
3011 /* geniCodeLogicAndOr - && || operations */
3012 /*-----------------------------------------------------------------*/
3014 geniCodeLogicAndOr (ast *tree, int lvl)
3017 symbol *falseLabel = newiTempLabel (NULL);
3018 symbol *trueLabel = newiTempLabel (NULL);
3019 symbol *exitLabel = newiTempLabel (NULL);
3020 operand *op, *result, *condition;
3022 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3023 They can be reenabled by executing the following block. If you find
3024 a decent optimization you could start right here:
3029 operand *leftOp, *rightOp;
3031 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3032 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3034 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3038 /* generate two IFX for the '&&' or '||' op */
3040 /* evaluate left operand */
3041 condition = ast2iCode (tree->left, lvl + 1);
3042 op = geniCodeRValue (condition, FALSE);
3044 /* test left operand */
3045 if (tree->opval.op == AND_OP)
3046 ic = newiCodeCondition (op, NULL, falseLabel);
3048 ic = newiCodeCondition (op, trueLabel, NULL);
3051 /* evaluate right operand */
3052 condition = ast2iCode (tree->right, lvl + 1);
3053 op = geniCodeRValue (condition, FALSE);
3055 /* test right operand */
3056 ic = newiCodeCondition (op, trueLabel, NULL);
3059 /* store 0 or 1 in result */
3060 result = newiTempOperand (newCharLink(), 1);
3062 geniCodeLabel (falseLabel);
3063 geniCodeAssign (result, operandFromLit (0), 0, 0);
3064 /* generate an unconditional goto */
3065 geniCodeGoto (exitLabel);
3067 geniCodeLabel (trueLabel);
3068 geniCodeAssign (result, operandFromLit (1), 0, 0);
3070 geniCodeLabel (exitLabel);
3075 /*-----------------------------------------------------------------*/
3076 /* geniCodeUnary - for a a generic unary operation */
3077 /*-----------------------------------------------------------------*/
3079 geniCodeUnary (operand * op, int oper)
3081 iCode *ic = newiCode (oper, op, NULL);
3083 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3085 return IC_RESULT (ic);
3088 /*-----------------------------------------------------------------*/
3089 /* geniCodeConditional - geniCode for '?' ':' operation */
3090 /*-----------------------------------------------------------------*/
3092 geniCodeConditional (ast * tree,int lvl)
3095 symbol *falseLabel = newiTempLabel (NULL);
3096 symbol *exitLabel = newiTempLabel (NULL);
3097 operand *cond = ast2iCode (tree->left,lvl+1);
3098 operand *true, *false, *result;
3100 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3104 true = ast2iCode (tree->right->left,lvl+1);
3106 /* move the value to a new Operand */
3107 result = newiTempOperand (tree->right->ftype, 0);
3108 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3110 /* generate an unconditional goto */
3111 geniCodeGoto (exitLabel);
3113 /* now for the right side */
3114 geniCodeLabel (falseLabel);
3116 false = ast2iCode (tree->right->right,lvl+1);
3117 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3119 /* create the exit label */
3120 geniCodeLabel (exitLabel);
3125 /*-----------------------------------------------------------------*/
3126 /* geniCodeAssign - generate code for assignment */
3127 /*-----------------------------------------------------------------*/
3129 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3132 sym_link *ltype = operandType (left);
3133 sym_link *rtype = operandType (right);
3135 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3137 werror (E_LVALUE_REQUIRED, "assignment");
3141 /* left is integral type and right is literal then
3142 check if the literal value is within bounds */
3143 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3145 checkConstantRange(ltype,
3146 OP_VALUE(right), "= operation", 0);
3149 /* if the left & right type don't exactly match */
3150 /* if pointer set then make sure the check is
3151 done with the type & not the pointer */
3152 /* then cast rights type to left */
3154 /* first check the type for pointer assignement */
3155 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3156 compareType (ltype, rtype) <= 0)
3158 if (compareType (ltype->next, rtype) < 0)
3159 right = geniCodeCast (ltype->next, right, TRUE);
3161 else if (compareType (ltype, rtype) < 0)
3162 right = geniCodeCast (ltype, right, TRUE);
3164 /* If left is a true symbol & ! volatile
3165 create an assignment to temporary for
3166 the right & then assign this temporary
3167 to the symbol. This is SSA (static single
3168 assignment). Isn't it simple and folks have
3169 published mountains of paper on it */
3170 if (IS_TRUE_SYMOP (left) &&
3171 !isOperandVolatile (left, FALSE) &&
3172 isOperandGlobal (left))
3176 if (IS_TRUE_SYMOP (right))
3177 sym = OP_SYMBOL (right);
3178 ic = newiCode ('=', NULL, right);
3179 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3180 SPIL_LOC (right) = sym;
3184 ic = newiCode ('=', NULL, right);
3185 IC_RESULT (ic) = left;
3188 /* if left isgptr flag is set then support
3189 routine will be required */
3193 ic->nosupdate = nosupdate;
3197 /*-----------------------------------------------------------------*/
3198 /* geniCodeDummyRead - generate code for dummy read */
3199 /*-----------------------------------------------------------------*/
3201 geniCodeDummyRead (operand * op)
3204 sym_link *type = operandType (op);
3206 if (!IS_VOLATILE(type))
3209 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3215 /*-----------------------------------------------------------------*/
3216 /* geniCodeSEParms - generate code for side effecting fcalls */
3217 /*-----------------------------------------------------------------*/
3219 geniCodeSEParms (ast * parms,int lvl)
3224 if (parms->type == EX_OP && parms->opval.op == PARAM)
3226 geniCodeSEParms (parms->left,lvl);
3227 geniCodeSEParms (parms->right,lvl);
3231 /* hack don't like this but too lazy to think of
3233 if (IS_ADDRESS_OF_OP (parms))
3234 parms->left->lvalue = 1;
3236 if (IS_CAST_OP (parms) &&
3237 IS_PTR (parms->ftype) &&
3238 IS_ADDRESS_OF_OP (parms->right))
3239 parms->right->left->lvalue = 1;
3241 parms->opval.oprnd =
3242 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3244 parms->type = EX_OPERAND;
3245 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3246 SPEC_ARGREG(parms->ftype);
3249 /*-----------------------------------------------------------------*/
3250 /* geniCodeParms - generates parameters */
3251 /*-----------------------------------------------------------------*/
3253 geniCodeParms (ast * parms, value *argVals, int *stack,
3254 sym_link * ftype, int lvl)
3262 if (argVals==NULL) {
3264 argVals = FUNC_ARGS (ftype);
3267 /* if this is a param node then do the left & right */
3268 if (parms->type == EX_OP && parms->opval.op == PARAM)
3270 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3271 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3275 /* get the parameter value */
3276 if (parms->type == EX_OPERAND)
3277 pval = parms->opval.oprnd;
3280 /* maybe this else should go away ?? */
3281 /* hack don't like this but too lazy to think of
3283 if (IS_ADDRESS_OF_OP (parms))
3284 parms->left->lvalue = 1;
3286 if (IS_CAST_OP (parms) &&
3287 IS_PTR (parms->ftype) &&
3288 IS_ADDRESS_OF_OP (parms->right))
3289 parms->right->left->lvalue = 1;
3291 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3294 /* if register parm then make it a send */
3295 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3296 IFFUNC_ISBUILTIN(ftype))
3298 ic = newiCode (SEND, pval, NULL);
3299 ic->argreg = SPEC_ARGREG(parms->etype);
3300 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3305 /* now decide whether to push or assign */
3306 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3310 operand *top = operandFromSymbol (argVals->sym);
3311 /* clear useDef and other bitVectors */
3312 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3313 geniCodeAssign (top, pval, 1, 0);
3317 sym_link *p = operandType (pval);
3319 ic = newiCode (IPUSH, pval, NULL);
3321 /* update the stack adjustment */
3322 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3327 argVals=argVals->next;
3331 /*-----------------------------------------------------------------*/
3332 /* geniCodeCall - generates temp code for calling */
3333 /*-----------------------------------------------------------------*/
3335 geniCodeCall (operand * left, ast * parms,int lvl)
3339 sym_link *type, *etype;
3343 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3344 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3345 werror (E_FUNCTION_EXPECTED);
3346 return operandFromValue(valueFromLit(0));
3349 /* take care of parameters with side-effecting
3350 function calls in them, this is required to take care
3351 of overlaying function parameters */
3352 geniCodeSEParms (parms,lvl);
3354 ftype = operandType (left);
3355 if (IS_FUNCPTR (ftype))
3356 ftype = ftype->next;
3358 /* first the parameters */
3359 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3361 /* now call : if symbol then pcall */
3362 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3363 ic = newiCode (PCALL, left, NULL);
3365 ic = newiCode (CALL, left, NULL);
3368 type = copyLinkChain (ftype->next);
3369 etype = getSpec (type);
3370 SPEC_EXTR (etype) = 0;
3371 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3375 /* stack adjustment after call */
3376 ic->parmBytes = stack;
3381 /*-----------------------------------------------------------------*/
3382 /* geniCodeReceive - generate intermediate code for "receive" */
3383 /*-----------------------------------------------------------------*/
3385 geniCodeReceive (value * args)
3387 unsigned char paramByteCounter = 0;
3389 /* for all arguments that are passed in registers */
3393 if (IS_REGPARM (args->etype))
3395 operand *opr = operandFromValue (args);
3397 symbol *sym = OP_SYMBOL (opr);
3400 /* we will use it after all optimizations
3401 and before liveRange calculation */
3402 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3405 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3406 options.stackAuto == 0 &&
3407 (!(options.model == MODEL_FLAT24)) )
3412 opl = newiTempOperand (args->type, 0);
3414 sym->reqv->key = sym->key;
3415 OP_SYMBOL (sym->reqv)->key = sym->key;
3416 OP_SYMBOL (sym->reqv)->isreqv = 1;
3417 OP_SYMBOL (sym->reqv)->islocal = 0;
3418 SPIL_LOC (sym->reqv) = sym;
3422 ic = newiCode (RECEIVE, NULL, NULL);
3423 ic->argreg = SPEC_ARGREG(args->etype);
3425 currFunc->recvSize = getSize (sym->type);
3428 IC_RESULT (ic) = opr;
3430 /* misuse of parmBytes (normally used for functions)
3431 * to save estimated stack position of this argument.
3432 * Normally this should be zero for RECEIVE iCodes.
3433 * No idea if this causes side effects on other ports. - dw
3435 ic->parmBytes = paramByteCounter;
3437 /* what stack position do we have? */
3438 paramByteCounter += getSize (sym->type);
3447 /*-----------------------------------------------------------------*/
3448 /* geniCodeFunctionBody - create the function body */
3449 /*-----------------------------------------------------------------*/
3451 geniCodeFunctionBody (ast * tree,int lvl)
3458 /* reset the auto generation */
3464 func = ast2iCode (tree->left,lvl+1);
3465 fetype = getSpec (operandType (func));
3467 savelineno = lineno;
3468 lineno = OP_SYMBOL (func)->lineDef;
3469 /* create an entry label */
3470 geniCodeLabel (entryLabel);
3471 lineno = savelineno;
3473 /* create a proc icode */
3474 ic = newiCode (FUNCTION, func, NULL);
3475 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3480 /* for all parameters that are passed
3481 on registers add a "receive" */
3482 geniCodeReceive (tree->values.args);
3484 /* generate code for the body */
3485 ast2iCode (tree->right,lvl+1);
3487 /* create a label for return */
3488 geniCodeLabel (returnLabel);
3490 /* now generate the end proc */
3491 ic = newiCode (ENDFUNCTION, func, NULL);
3497 /*-----------------------------------------------------------------*/
3498 /* geniCodeReturn - gen icode for 'return' statement */
3499 /*-----------------------------------------------------------------*/
3501 geniCodeReturn (operand * op)
3505 /* if the operand is present force an rvalue */
3507 op = geniCodeRValue (op, FALSE);
3509 ic = newiCode (RETURN, op, NULL);
3513 /*-----------------------------------------------------------------*/
3514 /* geniCodeIfx - generates code for extended if statement */
3515 /*-----------------------------------------------------------------*/
3517 geniCodeIfx (ast * tree,int lvl)
3520 operand *condition = ast2iCode (tree->left,lvl+1);
3523 /* if condition is null then exit */
3527 condition = geniCodeRValue (condition, FALSE);
3529 cetype = getSpec (operandType (condition));
3530 /* if the condition is a literal */
3531 if (IS_LITERAL (cetype))
3533 if (floatFromVal (condition->operand.valOperand))
3535 if (tree->trueLabel)
3536 geniCodeGoto (tree->trueLabel);
3542 if (tree->falseLabel)
3543 geniCodeGoto (tree->falseLabel);
3550 if (tree->trueLabel)
3552 ic = newiCodeCondition (condition,
3557 if (tree->falseLabel)
3558 geniCodeGoto (tree->falseLabel);
3562 ic = newiCodeCondition (condition,
3569 ast2iCode (tree->right,lvl+1);
3572 /*-----------------------------------------------------------------*/
3573 /* geniCodeJumpTable - tries to create a jump table for switch */
3574 /*-----------------------------------------------------------------*/
3576 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3578 int min, max, cnt = 1;
3585 int needRangeCheck = !optimize.noJTabBoundary
3586 || tree->values.switchVals.swDefault;
3587 sym_link *cetype = getSpec (operandType (cond));
3588 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3589 int sizeofMatchJump, sizeofJumpTable;
3592 if (!tree || !caseVals)
3595 /* the criteria for creating a jump table is */
3596 /* all integer numbers between the maximum & minimum must */
3597 /* be present , the maximum value should not exceed 255 */
3598 /* If not all integer numbers are present the algorithm */
3599 /* inserts jumps to the default label for the missing numbers */
3600 /* and decides later whether it is worth it */
3601 min = (int) floatFromVal (vch = caseVals);
3608 max = (int) floatFromVal (vch);
3610 /* Exit if the range is too large to handle with a jump table. */
3611 if (1 + max - min > port->jumptableCost.maxCount)
3614 switch (getSize (operandType (cond)))
3616 case 1: sizeIndex = 0; break;
3617 case 2: sizeIndex = 1; break;
3618 case 4: sizeIndex = 2; break;
3622 /* Compute the size cost of the range check and subtraction. */
3624 sizeofZeroMinCost = 0;
3628 if (!(min==0 && IS_UNSIGNED (cetype)))
3629 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3630 if (!IS_UNSIGNED (cetype))
3631 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3632 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3635 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3637 /* If the size cost of handling a non-zero minimum exceeds the */
3638 /* cost of extending the range down to zero, then it might be */
3639 /* better to extend the range to zero. */
3640 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3641 >= (min * port->jumptableCost.sizeofElement))
3643 /* Only extend the jump table if it would still be manageable. */
3644 if (1 + max <= port->jumptableCost.maxCount)
3647 if (IS_UNSIGNED (cetype))
3650 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3654 /* Compute the total size cost of a jump table. */
3655 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3656 + port->jumptableCost.sizeofDispatch
3657 + sizeofMinCost + sizeofMaxCost;
3659 /* Compute the total size cost of a match & jump sequence */
3660 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3662 /* If the size cost of the jump table is uneconomical then exit */
3663 if (sizeofMatchJump < sizeofJumpTable)
3666 /* The jump table is preferable. */
3668 /* First, a label for the default or missing cases. */
3669 if (tree->values.switchVals.swDefault)
3671 SNPRINTF (buffer, sizeof(buffer),
3673 tree->values.switchVals.swNum);
3677 SNPRINTF (buffer, sizeof(buffer),
3679 tree->values.switchVals.swNum);
3681 falseLabel = newiTempLabel (buffer);
3683 /* Build the list of labels for the jump table. */
3685 t = (int) floatFromVal (vch);
3686 for (i=min; i<=max; i++)
3690 /* Explicit case: make a new label for it. */
3691 SNPRINTF (buffer, sizeof(buffer),
3693 tree->values.switchVals.swNum,
3695 addSet (&labels, newiTempLabel (buffer));
3698 t = (int) floatFromVal (vch);
3702 /* Implicit case: use the default label. */
3703 addSet (&labels, falseLabel);
3707 /* first we rule out the boundary conditions */
3708 /* if only optimization says so */
3711 sym_link *cetype = getSpec (operandType (cond));
3712 /* no need to check the lower bound if
3713 the condition is unsigned & minimum value is zero */
3714 if (!(min == 0 && IS_UNSIGNED (cetype)))
3716 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3717 ic = newiCodeCondition (boundary, falseLabel, NULL);
3721 /* now for upper bounds */
3722 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3723 ic = newiCodeCondition (boundary, falseLabel, NULL);
3727 /* if the min is not zero then we no make it zero */
3730 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3731 if (!IS_LITERAL(getSpec(operandType(cond))))
3732 setOperandType (cond, UCHARTYPE);
3735 /* now create the jumptable */
3736 ic = newiCode (JUMPTABLE, NULL, NULL);
3737 IC_JTCOND (ic) = cond;
3738 IC_JTLABELS (ic) = labels;
3743 /*-----------------------------------------------------------------*/
3744 /* geniCodeSwitch - changes a switch to a if statement */
3745 /*-----------------------------------------------------------------*/
3747 geniCodeSwitch (ast * tree,int lvl)
3750 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3751 value *caseVals = tree->values.switchVals.swVals;
3752 symbol *trueLabel, *falseLabel;
3754 /* If the condition is a literal, then just jump to the */
3755 /* appropriate case label. */
3756 if (IS_LITERAL(getSpec(operandType(cond))))
3758 int switchVal, caseVal;
3760 switchVal = (int) floatFromVal (cond->operand.valOperand);
3763 caseVal = (int) floatFromVal (caseVals);
3764 if (caseVal == switchVal)
3766 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3767 tree->values.switchVals.swNum, caseVal);
3768 trueLabel = newiTempLabel (buffer);
3769 geniCodeGoto (trueLabel);
3772 caseVals = caseVals->next;
3774 goto defaultOrBreak;
3777 /* If cond is volatile, it might change while we are trying to */
3778 /* find the matching case. To avoid this possibility, make a */
3779 /* non-volatile copy to use instead. */
3780 if (IS_OP_VOLATILE (cond))
3785 newcond = newiTempOperand (operandType (cond), TRUE);
3786 newcond->isvolatile = 0;
3787 ic = newiCode ('=', NULL, cond);
3788 IC_RESULT (ic) = newcond;
3793 /* if we can make this a jump table */
3794 if (geniCodeJumpTable (cond, caseVals, tree))
3795 goto jumpTable; /* no need for the comparison */
3797 /* for the cases defined do */
3801 operand *compare = geniCodeLogic (cond,
3802 operandFromValue (caseVals),
3805 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3806 tree->values.switchVals.swNum,
3807 (int) floatFromVal (caseVals));
3808 trueLabel = newiTempLabel (buffer);
3810 ic = newiCodeCondition (compare, trueLabel, NULL);
3812 caseVals = caseVals->next;
3817 /* if default is present then goto break else break */
3818 if (tree->values.switchVals.swDefault)
3820 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3824 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3827 falseLabel = newiTempLabel (buffer);
3828 geniCodeGoto (falseLabel);
3831 ast2iCode (tree->right,lvl+1);
3834 /*-----------------------------------------------------------------*/
3835 /* geniCodeInline - intermediate code for inline assembler */
3836 /*-----------------------------------------------------------------*/
3838 geniCodeInline (ast * tree)
3842 ic = newiCode (INLINEASM, NULL, NULL);
3843 IC_INLINE (ic) = tree->values.inlineasm;
3847 /*-----------------------------------------------------------------*/
3848 /* geniCodeArrayInit - intermediate code for array initializer */
3849 /*-----------------------------------------------------------------*/
3851 geniCodeArrayInit (ast * tree, operand *array)
3855 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3856 ic = newiCode (ARRAYINIT, array, NULL);
3857 IC_ARRAYILIST (ic) = tree->values.constlist;
3859 operand *left=newOperand(), *right=newOperand();
3860 left->type=right->type=SYMBOL;
3861 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3862 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3863 ic = newiCode (ARRAYINIT, left, right);
3868 /*-----------------------------------------------------------------*/
3869 /* geniCodeCritical - intermediate code for a critical statement */
3870 /*-----------------------------------------------------------------*/
3872 geniCodeCritical (ast *tree, int lvl)
3878 if (!options.stackAuto)
3880 type = newLink(SPECIFIER);
3881 SPEC_VOLATILE(type) = 1;
3882 SPEC_NOUN(type) = V_BIT;
3883 SPEC_SCLS(type) = S_BIT;
3884 SPEC_BLEN(type) = 1;
3885 SPEC_BSTR(type) = 0;
3886 op = newiTempOperand(type, 1);
3889 /* If op is NULL, the original interrupt state will saved on */
3890 /* the stack. Otherwise, it will be saved in op. */
3892 /* Generate a save of the current interrupt state & disable */
3893 ic = newiCode (CRITICAL, NULL, NULL);
3894 IC_RESULT (ic) = op;
3897 /* Generate the critical code sequence */
3898 if (tree->left && tree->left->type == EX_VALUE)
3899 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3901 ast2iCode (tree->left,lvl+1);
3903 /* Generate a restore of the original interrupt state */
3904 ic = newiCode (ENDCRITICAL, NULL, op);
3908 /*-----------------------------------------------------------------*/
3909 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3910 /* particular case. Ie : assigning or dereferencing array or ptr */
3911 /*-----------------------------------------------------------------*/
3912 set * lvaluereqSet = NULL;
3913 typedef struct lvalItem
3920 /*-----------------------------------------------------------------*/
3921 /* addLvaluereq - add a flag for lvalreq for current ast level */
3922 /*-----------------------------------------------------------------*/
3923 void addLvaluereq(int lvl)
3925 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3928 addSetHead(&lvaluereqSet,lpItem);
3931 /*-----------------------------------------------------------------*/
3932 /* delLvaluereq - del a flag for lvalreq for current ast level */
3933 /*-----------------------------------------------------------------*/
3937 lpItem = getSet(&lvaluereqSet);
3938 if(lpItem) Safe_free(lpItem);
3940 /*-----------------------------------------------------------------*/
3941 /* clearLvaluereq - clear lvalreq flag */
3942 /*-----------------------------------------------------------------*/
3943 void clearLvaluereq()
3946 lpItem = peekSet(lvaluereqSet);
3947 if(lpItem) lpItem->req = 0;
3949 /*-----------------------------------------------------------------*/
3950 /* getLvaluereq - get the last lvalreq level */
3951 /*-----------------------------------------------------------------*/
3952 int getLvaluereqLvl()
3955 lpItem = peekSet(lvaluereqSet);
3956 if(lpItem) return lpItem->lvl;
3959 /*-----------------------------------------------------------------*/
3960 /* isLvaluereq - is lvalreq valid for this level ? */
3961 /*-----------------------------------------------------------------*/
3962 int isLvaluereq(int lvl)
3965 lpItem = peekSet(lvaluereqSet);
3966 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3970 /*-----------------------------------------------------------------*/
3971 /* ast2iCode - creates an icodeList from an ast */
3972 /*-----------------------------------------------------------------*/
3974 ast2iCode (ast * tree,int lvl)
3976 operand *left = NULL;
3977 operand *right = NULL;
3981 /* set the global variables for filename & line number */
3983 filename = tree->filename;
3985 lineno = tree->lineno;
3987 block = tree->block;
3989 scopeLevel = tree->level;
3991 seqPoint = tree->seqPoint;
3993 if (tree->type == EX_VALUE)
3994 return operandFromValue (tree->opval.val);
3996 if (tree->type == EX_LINK)
3997 return operandFromLink (tree->opval.lnk);
3999 /* if we find a nullop */
4000 if (tree->type == EX_OP &&
4001 (tree->opval.op == NULLOP ||
4002 tree->opval.op == BLOCK))
4004 if (tree->left && tree->left->type == EX_VALUE)
4005 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4007 ast2iCode (tree->left,lvl+1);
4008 if (tree->right && tree->right->type == EX_VALUE)
4009 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4011 ast2iCode (tree->right,lvl+1);
4015 /* special cases for not evaluating */
4016 if (tree->opval.op != ':' &&
4017 tree->opval.op != '?' &&
4018 tree->opval.op != CALL &&
4019 tree->opval.op != IFX &&
4020 tree->opval.op != AND_OP &&
4021 tree->opval.op != OR_OP &&
4022 tree->opval.op != LABEL &&
4023 tree->opval.op != GOTO &&
4024 tree->opval.op != SWITCH &&
4025 tree->opval.op != FUNCTION &&
4026 tree->opval.op != INLINEASM &&
4027 tree->opval.op != CRITICAL)
4030 if (IS_ASSIGN_OP (tree->opval.op) ||
4031 IS_DEREF_OP (tree) ||
4032 (tree->opval.op == '&' && !tree->right) ||
4033 tree->opval.op == PTR_OP)
4036 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4037 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4040 left = operandFromAst (tree->left,lvl);
4042 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4043 left = geniCodeRValue (left, TRUE);
4047 left = operandFromAst (tree->left,lvl);
4049 if (tree->opval.op == INC_OP ||
4050 tree->opval.op == DEC_OP)
4053 right = operandFromAst (tree->right,lvl);
4058 right = operandFromAst (tree->right,lvl);
4062 /* now depending on the type of operand */
4063 /* this will be a biggy */
4064 switch (tree->opval.op)
4067 case '[': /* array operation */
4069 //sym_link *ltype = operandType (left);
4070 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4071 left = geniCodeRValue (left, FALSE);
4072 right = geniCodeRValue (right, TRUE);
4075 return geniCodeArray (left, right,lvl);
4077 case '.': /* structure dereference */
4078 if (IS_PTR (operandType (left)))
4079 left = geniCodeRValue (left, TRUE);
4081 left = geniCodeRValue (left, FALSE);
4083 return geniCodeStruct (left, right, tree->lvalue);
4085 case PTR_OP: /* structure pointer dereference */
4088 pType = operandType (left);
4089 left = geniCodeRValue (left, TRUE);
4091 setOClass (pType, getSpec (operandType (left)));
4094 return geniCodeStruct (left, right, tree->lvalue);
4096 case INC_OP: /* increment operator */
4098 return geniCodePostInc (left);
4100 return geniCodePreInc (right, tree->lvalue);
4102 case DEC_OP: /* decrement operator */
4104 return geniCodePostDec (left);
4106 return geniCodePreDec (right, tree->lvalue);
4108 case '&': /* bitwise and or address of operator */
4110 { /* this is a bitwise operator */
4111 left = geniCodeRValue (left, FALSE);
4112 right = geniCodeRValue (right, FALSE);
4113 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4116 return geniCodeAddressOf (left);
4118 case '|': /* bitwise or & xor */
4120 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4121 geniCodeRValue (right, FALSE),
4126 return geniCodeDivision (geniCodeRValue (left, FALSE),
4127 geniCodeRValue (right, FALSE),
4128 getResultTypeFromType (tree->ftype));
4131 return geniCodeModulus (geniCodeRValue (left, FALSE),
4132 geniCodeRValue (right, FALSE),
4133 getResultTypeFromType (tree->ftype));
4136 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4137 geniCodeRValue (right, FALSE),
4138 getResultTypeFromType (tree->ftype));
4140 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4144 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4145 geniCodeRValue (right, FALSE),
4146 getResultTypeFromType (tree->ftype));
4148 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4152 return geniCodeAdd (geniCodeRValue (left, FALSE),
4153 geniCodeRValue (right, FALSE),
4154 getResultTypeFromType (tree->ftype),
4157 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4160 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4161 geniCodeRValue (right, FALSE),
4162 getResultTypeFromType (tree->ftype));
4165 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4166 geniCodeRValue (right, FALSE));
4168 #if 0 // this indeed needs a second thought
4172 // let's keep this simple: get the rvalue we need
4173 op=geniCodeRValue (right, FALSE);
4174 // now cast it to whatever we want
4175 op=geniCodeCast (operandType(left), op, FALSE);
4176 // if this is going to be used as an lvalue, make it so
4182 #else // bug #604575, is it a bug ????
4183 return geniCodeCast (operandType (left),
4184 geniCodeRValue (right, FALSE), FALSE);
4191 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4196 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4197 setOperandType (op, UCHARTYPE);
4202 return geniCodeLogicAndOr (tree, lvl);
4209 /* different compilers (even different gccs) evaluate
4210 the two calls in a different order. to get the same
4211 result on all machines we've to specify a clear sequence.
4212 return geniCodeLogic (geniCodeRValue (left, FALSE),
4213 geniCodeRValue (right, FALSE),
4217 operand *leftOp, *rightOp;
4219 leftOp = geniCodeRValue (left , FALSE);
4220 rightOp = geniCodeRValue (right, FALSE);
4222 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4225 return geniCodeConditional (tree,lvl);
4228 return operandFromLit (getSize (tree->right->ftype));
4232 sym_link *rtype = operandType (right);
4233 sym_link *ltype = operandType (left);
4234 if (IS_PTR (rtype) && IS_ITEMP (right)
4235 && right->isaddr && compareType (rtype->next, ltype) == 1)
4236 right = geniCodeRValue (right, TRUE);
4238 right = geniCodeRValue (right, FALSE);
4240 geniCodeAssign (left, right, 0, 1);
4245 geniCodeAssign (left,
4246 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4248 geniCodeRValue (right, FALSE),
4249 getResultTypeFromType (tree->ftype)),
4254 geniCodeAssign (left,
4255 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4257 geniCodeRValue (right, FALSE),
4258 getResultTypeFromType (tree->ftype)),
4262 geniCodeAssign (left,
4263 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4265 geniCodeRValue (right, FALSE),
4266 getResultTypeFromType (tree->ftype)),
4270 sym_link *rtype = operandType (right);
4271 sym_link *ltype = operandType (left);
4272 if (IS_PTR (rtype) && IS_ITEMP (right)
4273 && right->isaddr && compareType (rtype->next, ltype) == 1)
4274 right = geniCodeRValue (right, TRUE);
4276 right = geniCodeRValue (right, FALSE);
4279 return geniCodeAssign (left,
4280 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4283 getResultTypeFromType (tree->ftype),
4289 sym_link *rtype = operandType (right);
4290 sym_link *ltype = operandType (left);
4291 if (IS_PTR (rtype) && IS_ITEMP (right)
4292 && right->isaddr && compareType (rtype->next, ltype) == 1)
4294 right = geniCodeRValue (right, TRUE);
4298 right = geniCodeRValue (right, FALSE);
4301 geniCodeAssign (left,
4302 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4305 getResultTypeFromType (tree->ftype)),
4310 geniCodeAssign (left,
4311 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4313 geniCodeRValue (right, FALSE),
4314 getResultTypeFromType (tree->ftype)),
4318 geniCodeAssign (left,
4319 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4321 geniCodeRValue (right, FALSE)), 0, 1);
4324 geniCodeAssign (left,
4325 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4327 geniCodeRValue (right, FALSE),
4329 operandType (left)), 0, 1);
4332 geniCodeAssign (left,
4333 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4335 geniCodeRValue (right, FALSE),
4337 operandType (left)), 0, 1);
4340 geniCodeAssign (left,
4341 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4343 geniCodeRValue (right, FALSE),
4345 operandType (left)), 0, 1);
4347 return geniCodeRValue (right, FALSE);
4350 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4353 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4354 return ast2iCode (tree->right,lvl+1);
4357 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4358 return ast2iCode (tree->right,lvl+1);
4361 geniCodeFunctionBody (tree,lvl);
4365 geniCodeReturn (right);
4369 geniCodeIfx (tree,lvl);
4373 geniCodeSwitch (tree,lvl);
4377 geniCodeInline (tree);
4381 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4385 geniCodeCritical (tree, lvl);
4391 /*-----------------------------------------------------------------*/
4392 /* reverseICChain - gets from the list and creates a linkedlist */
4393 /*-----------------------------------------------------------------*/
4400 while ((loop = getSet (&iCodeChain)))
4412 /*-----------------------------------------------------------------*/
4413 /* iCodeFromAst - given an ast will convert it to iCode */
4414 /*-----------------------------------------------------------------*/
4416 iCodeFromAst (ast * tree)
4418 returnLabel = newiTempLabel ("_return");
4419 entryLabel = newiTempLabel ("_entry");
4421 return reverseiCChain ();
4424 static const char *opTypeToStr(OPTYPE op)
4428 case SYMBOL: return "symbol";
4429 case VALUE: return "value";
4430 case TYPE: return "type";
4432 return "undefined type";
4436 operand *validateOpType(operand *op,
4443 if (op && op->type == type)
4448 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4449 " expected %s, got %s\n",
4450 macro, args, file, line,
4451 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4453 return op; // never reached, makes compiler happy.