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 {GETABIT, "gabit", picGenericOne, NULL},
84 {GETBYTE, "gbyte", picGenericOne, NULL},
85 {GETWORD, "gword", picGenericOne, NULL},
86 {UNARYMINUS, "-", picGenericOne, NULL},
87 {IPUSH, "push", picGenericOne, NULL},
88 {IPOP, "pop", picGenericOne, NULL},
89 {CALL, "call", picGenericOne, NULL},
90 {PCALL, "pcall", picGenericOne, NULL},
91 {FUNCTION, "proc", picGenericOne, NULL},
92 {ENDFUNCTION, "eproc", picGenericOne, NULL},
93 {RETURN, "ret", picGenericOne, NULL},
94 {'+', "+", picGeneric, NULL},
95 {'-', "-", picGeneric, NULL},
96 {'*', "*", picGeneric, NULL},
97 {'/', "/", picGeneric, NULL},
98 {'%', "%", picGeneric, NULL},
99 {'>', ">", picGeneric, NULL},
100 {'<', "<", picGeneric, NULL},
101 {LE_OP, "<=", picGeneric, NULL},
102 {GE_OP, ">=", picGeneric, NULL},
103 {EQ_OP, "==", picGeneric, NULL},
104 {NE_OP, "!=", picGeneric, NULL},
105 {AND_OP, "&&", picGeneric, NULL},
106 {OR_OP, "||", picGeneric, NULL},
107 {'^', "^", picGeneric, NULL},
108 {'|', "|", picGeneric, NULL},
109 {BITWISEAND, "&", picGeneric, NULL},
110 {LEFT_OP, "<<", picGeneric, NULL},
111 {RIGHT_OP, ">>", picGeneric, NULL},
112 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
113 {ADDRESS_OF, "&", picAddrOf, NULL},
114 {CAST, "<>", picCast, NULL},
115 {'=', ":=", picAssign, NULL},
116 {LABEL, "", picLabel, NULL},
117 {GOTO, "", picGoto, NULL},
118 {JUMPTABLE, "jtab", picJumpTable, NULL},
119 {IFX, "if", picIfx, NULL},
120 {INLINEASM, "", picInline, NULL},
121 {RECEIVE, "recv", picReceive, NULL},
122 {SEND, "send", picGenericOne, NULL},
123 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
124 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
125 {CRITICAL, "critical_start", picCritical, NULL},
126 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
127 {SWAP, "swap", picGenericOne, NULL}
130 /*-----------------------------------------------------------------*/
131 /* checkConstantRange: check a constant against the type */
132 /*-----------------------------------------------------------------*/
135 /* pedantic=0: allmost anything is allowed as long as the absolute
136 value is within the bit range of the type, and -1 is treated as
137 0xf..f for unsigned types (e.g. in assign)
138 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
139 pedantic>1: "char c=200" is not allowed (evaluates to -56)
142 void checkConstantRange(sym_link *ltype, value *val, char *msg,
149 max = pow ((double)2.0, (double)bitsForType(ltype));
151 if (IS_LONG(val->type)) {
152 if (IS_UNSIGNED(val->type)) {
153 v=SPEC_CVAL(val->type).v_ulong;
155 v=SPEC_CVAL(val->type).v_long;
158 if (IS_UNSIGNED(val->type)) {
159 v=SPEC_CVAL(val->type).v_uint;
161 v=SPEC_CVAL(val->type).v_int;
167 // this could be a good idea
168 if (options.pedantic)
172 if (IS_FLOAT(ltype)) {
177 if (IS_FIXED(ltype)) {
182 if (!IS_UNSIGNED(val->type) && v<0) {
184 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
190 // if very pedantic: "char c=200" is not allowed
191 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
192 max = max/2 + negative;
199 #if 0 // temporary disabled, leaving the warning as a reminder
201 SNPRINTF (message, sizeof(message), "for %s %s in %s",
202 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
203 nounName(ltype), msg);
204 werror (W_CONST_RANGE, message);
212 /*-----------------------------------------------------------------*/
213 /* operandName - returns the name of the operand */
214 /*-----------------------------------------------------------------*/
216 printOperand (operand * op, FILE * file)
233 opetype = getSpec (operandType (op));
234 if (IS_FLOAT (opetype))
235 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
236 else if (IS_FIXED16X16 (opetype))
237 fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
239 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
240 printTypeChain (operandType (op), file);
247 if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
248 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}" , */
249 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
251 OP_LIVEFROM (op), OP_LIVETO (op),
252 OP_SYMBOL (op)->stack,
253 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
254 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
255 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
259 printTypeChain (operandType (op), file);
260 if (SPIL_LOC (op) && IS_ITEMP (op))
261 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
266 /* if assigned to registers */
267 if (OP_SYMBOL (op)->nRegs)
269 if (OP_SYMBOL (op)->isspilt)
271 if (!OP_SYMBOL (op)->remat)
272 if (OP_SYMBOL (op)->usl.spillLoc)
273 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
274 OP_SYMBOL (op)->usl.spillLoc->rname :
275 OP_SYMBOL (op)->usl.spillLoc->name));
277 fprintf (file, "[err]");
279 fprintf (file, "[remat]");
285 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
286 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
290 //#else /* } else { */
292 /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
293 fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
295 if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
297 fprintf (file, "[lr%d:%d so:%d]",
298 OP_LIVEFROM (op), OP_LIVETO (op),
299 OP_SYMBOL (op)->stack);
302 if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
305 printTypeChain (operandType (op), file);
306 if (SPIL_LOC (op) && IS_ITEMP (op))
307 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
311 /* if assigned to registers */
312 if (OP_SYMBOL (op)->nRegs)
314 if (OP_SYMBOL (op)->isspilt)
316 if (!OP_SYMBOL (op)->remat)
317 if (OP_SYMBOL (op)->usl.spillLoc)
318 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
319 OP_SYMBOL (op)->usl.spillLoc->rname :
320 OP_SYMBOL (op)->usl.spillLoc->name));
322 fprintf (file, "[err]");
324 fprintf (file, "[remat]");
330 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
331 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
341 printTypeChain (op->operand.typeOperand, file);
347 fprintf (file, "\n");
352 /*-----------------------------------------------------------------*/
353 /* print functions */
354 /*-----------------------------------------------------------------*/
355 PRINTFUNC (picGetValueAtAddr)
358 printOperand (IC_RESULT (ic), of);
361 printOperand (IC_LEFT (ic), of);
367 PRINTFUNC (picSetValueAtAddr)
371 printOperand (IC_LEFT (ic), of);
372 fprintf (of, "] = ");
373 printOperand (IC_RIGHT (ic), of);
377 PRINTFUNC (picAddrOf)
380 printOperand (IC_RESULT (ic), of);
381 if (IS_ITEMP (IC_LEFT (ic)))
384 fprintf (of, " = &[");
385 printOperand (IC_LEFT (ic), of);
388 if (IS_ITEMP (IC_LEFT (ic)))
389 fprintf (of, " offsetAdd ");
392 printOperand (IC_RIGHT (ic), of);
394 if (IS_ITEMP (IC_LEFT (ic)))
400 PRINTFUNC (picJumpTable)
405 fprintf (of, "%s\t", s);
406 printOperand (IC_JTCOND (ic), of);
408 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
409 sym = setNextItem (IC_JTLABELS (ic)))
410 fprintf (of, "\t\t\t%s\n", sym->name);
413 PRINTFUNC (picGeneric)
416 printOperand (IC_RESULT (ic), of);
418 printOperand (IC_LEFT (ic), of);
419 fprintf (of, " %s ", s);
420 printOperand (IC_RIGHT (ic), of);
424 PRINTFUNC (picGenericOne)
429 printOperand (IC_RESULT (ic), of);
435 fprintf (of, "%s ", s);
436 printOperand (IC_LEFT (ic), of);
439 if (!IC_RESULT (ic) && !IC_LEFT (ic))
442 if (ic->op == SEND || ic->op == RECEIVE) {
443 fprintf(of,"{argreg = %d}",ic->argreg);
445 if (ic->op == IPUSH) {
446 fprintf(of,"{parmPush = %d}",ic->parmPush);
454 printOperand (IC_RESULT (ic), of);
456 printOperand (IC_LEFT (ic), of);
457 printOperand (IC_RIGHT (ic), of);
462 PRINTFUNC (picAssign)
466 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
469 printOperand (IC_RESULT (ic), of);
471 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
474 fprintf (of, " %s ", s);
475 printOperand (IC_RIGHT (ic), of);
482 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
488 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
495 printOperand (IC_COND (ic), of);
498 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
501 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
503 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
507 PRINTFUNC (picInline)
509 fprintf (of, "%s", IC_INLINE (ic));
512 PRINTFUNC (picReceive)
514 printOperand (IC_RESULT (ic), of);
515 fprintf (of, " = %s ", s);
516 printOperand (IC_LEFT (ic), of);
520 PRINTFUNC (picDummyRead)
523 fprintf (of, "%s ", s);
524 printOperand (IC_RIGHT (ic), of);
528 PRINTFUNC (picCritical)
532 printOperand (IC_RESULT (ic), of);
534 fprintf (of, "(stack)");
535 fprintf (of, " = %s ", s);
539 PRINTFUNC (picEndCritical)
542 fprintf (of, "%s = ", s);
544 printOperand (IC_RIGHT (ic), of);
546 fprintf (of, "(stack)");
550 /*-----------------------------------------------------------------*/
551 /* piCode - prints one iCode */
552 /*-----------------------------------------------------------------*/
554 piCode (void *item, FILE * of)
562 icTab = getTableEntry (ic->op);
563 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
564 ic->filename, ic->lineno,
565 ic->seq, ic->key, ic->depth, ic->supportRtn);
566 icTab->iCodePrint (of, ic, icTab->printName);
572 printiCChain(ic,stdout);
574 /*-----------------------------------------------------------------*/
575 /* printiCChain - prints intermediate code for humans */
576 /*-----------------------------------------------------------------*/
578 printiCChain (iCode * icChain, FILE * of)
585 for (loop = icChain; loop; loop = loop->next)
587 if ((icTab = getTableEntry (loop->op)))
589 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
590 loop->filename, loop->lineno,
591 loop->seq, loop->key, loop->depth, loop->supportRtn);
593 icTab->iCodePrint (of, loop, icTab->printName);
599 /*-----------------------------------------------------------------*/
600 /* newOperand - allocate, init & return a new iCode */
601 /*-----------------------------------------------------------------*/
607 op = Safe_alloc ( sizeof (operand));
613 /*-----------------------------------------------------------------*/
614 /* newiCode - create and return a new iCode entry initialised */
615 /*-----------------------------------------------------------------*/
617 newiCode (int op, operand * left, operand * right)
621 ic = Safe_alloc ( sizeof (iCode));
623 ic->seqPoint = seqPoint;
625 ic->filename = filename;
627 ic->level = scopeLevel;
629 ic->key = iCodeKey++;
631 IC_RIGHT (ic) = right;
636 /*-----------------------------------------------------------------*/
637 /* newiCode for conditional statements */
638 /*-----------------------------------------------------------------*/
640 newiCodeCondition (operand * condition,
646 if (IS_VOID(operandType(condition))) {
647 werror(E_VOID_VALUE_USED);
650 ic = newiCode (IFX, NULL, NULL);
651 IC_COND (ic) = condition;
652 IC_TRUE (ic) = trueLabel;
653 IC_FALSE (ic) = falseLabel;
657 /*-----------------------------------------------------------------*/
658 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
659 /*-----------------------------------------------------------------*/
661 newiCodeLabelGoto (int op, symbol * label)
665 ic = newiCode (op, NULL, NULL);
669 IC_RIGHT (ic) = NULL;
670 IC_RESULT (ic) = NULL;
674 /*-----------------------------------------------------------------*/
675 /* newiTemp - allocate & return a newItemp Variable */
676 /*-----------------------------------------------------------------*/
684 SNPRINTF (buffer, sizeof(buffer), "%s", s);
688 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
691 itmp = newSymbol (buffer, 1);
692 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
698 /*-----------------------------------------------------------------*/
699 /* newiTempLabel - creates a temp variable label */
700 /*-----------------------------------------------------------------*/
702 newiTempLabel (char *s)
706 /* check if this already exists */
707 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
712 itmplbl = newSymbol (s, 1);
716 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
717 itmplbl = newSymbol (buffer, 1);
722 itmplbl->key = labelKey++;
723 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
727 /*-----------------------------------------------------------------*/
728 /* newiTempLoopHeaderLabel - creates a new loop header label */
729 /*-----------------------------------------------------------------*/
731 newiTempLoopHeaderLabel (bool pre)
735 SNPRINTF (buffer, sizeof(buffer), pre ? "preHeaderLbl%d" : LOOPEXITLBL "%d",
737 itmplbl = newSymbol (buffer, 1);
741 itmplbl->key = labelKey++;
742 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
747 /*-----------------------------------------------------------------*/
748 /* initiCode - initialises some iCode related stuff */
749 /*-----------------------------------------------------------------*/
756 /*-----------------------------------------------------------------*/
757 /* copyiCode - make a copy of the iCode given */
758 /*-----------------------------------------------------------------*/
760 copyiCode (iCode * ic)
762 iCode *nic = newiCode (ic->op, NULL, NULL);
764 nic->lineno = ic->lineno;
765 nic->filename = ic->filename;
766 nic->block = ic->block;
767 nic->level = ic->level;
768 nic->parmBytes = ic->parmBytes;
770 /* deal with the special cases first */
774 IC_COND (nic) = operandFromOperand (IC_COND (ic));
775 IC_TRUE (nic) = IC_TRUE (ic);
776 IC_FALSE (nic) = IC_FALSE (ic);
780 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
781 IC_JTLABELS (nic) = IC_JTLABELS (ic);
786 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
787 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
791 IC_INLINE (nic) = IC_INLINE (ic);
795 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
799 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
800 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
801 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
807 /*-----------------------------------------------------------------*/
808 /* getTableEntry - gets the table entry for the given operator */
809 /*-----------------------------------------------------------------*/
811 getTableEntry (int oper)
815 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
816 if (oper == codeTable[i].icode)
817 return &codeTable[i];
822 /*-----------------------------------------------------------------*/
823 /* newiTempOperand - new intermediate temp operand */
824 /*-----------------------------------------------------------------*/
826 newiTempOperand (sym_link * type, char throwType)
829 operand *op = newOperand ();
833 itmp = newiTemp (NULL);
835 etype = getSpec (type);
837 if (IS_LITERAL (etype))
840 /* copy the type information */
842 itmp->etype = getSpec (itmp->type = (throwType ? type :
843 copyLinkChain (type)));
844 if (IS_LITERAL (itmp->etype))
846 SPEC_SCLS (itmp->etype) = S_REGISTER;
847 SPEC_OCLS (itmp->etype) = reg;
850 op->operand.symOperand = itmp;
851 op->key = itmp->key = ++operandKey;
855 /*-----------------------------------------------------------------*/
856 /* operandType - returns the type chain for an operand */
857 /*-----------------------------------------------------------------*/
859 operandType (operand * op)
861 /* depending on type of operand */
866 return op->operand.valOperand->type;
869 return op->operand.symOperand->type;
872 return op->operand.typeOperand;
874 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
875 " operand type not known ");
876 assert (0); /* should never come here */
877 /* Just to keep the compiler happy */
878 return (sym_link *) 0;
882 /*-----------------------------------------------------------------*/
883 /* isParamterToCall - will return 1 if op is a parameter to args */
884 /*-----------------------------------------------------------------*/
886 isParameterToCall (value * args, operand * op)
890 wassert (IS_SYMOP(op));
895 isSymbolEqual (op->operand.symOperand, tval->sym))
902 /*-----------------------------------------------------------------*/
903 /* isOperandGlobal - return 1 if operand is a global variable */
904 /*-----------------------------------------------------------------*/
906 isOperandGlobal (operand * op)
915 (op->operand.symOperand->level == 0 ||
916 IS_STATIC (op->operand.symOperand->etype) ||
917 IS_EXTERN (op->operand.symOperand->etype))
924 /*-----------------------------------------------------------------*/
925 /* isOperandVolatile - return 1 if the operand is volatile */
926 /*-----------------------------------------------------------------*/
928 isOperandVolatile (operand * op, bool chkTemp)
933 if (IS_ITEMP (op) && !chkTemp)
936 opetype = getSpec (optype = operandType (op));
938 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
941 if (IS_VOLATILE (opetype))
946 /*-----------------------------------------------------------------*/
947 /* isOperandLiteral - returns 1 if an operand contains a literal */
948 /*-----------------------------------------------------------------*/
950 isOperandLiteral (operand * op)
957 opetype = getSpec (operandType (op));
959 if (IS_LITERAL (opetype))
965 /*-----------------------------------------------------------------*/
966 /* isOperandInFarSpace - will return true if operand is in farSpace */
967 /*-----------------------------------------------------------------*/
969 isOperandInFarSpace (operand * op)
979 if (!IS_TRUE_SYMOP (op))
982 etype = SPIL_LOC (op)->etype;
988 etype = getSpec (operandType (op));
990 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
993 /*-----------------------------------------------------------------*/
994 /* isOperandInPagedSpace - return true if operand is in pagedSpace */
995 /*-----------------------------------------------------------------*/
997 isOperandInPagedSpace (operand * op)
1007 if (!IS_TRUE_SYMOP (op))
1010 etype = SPIL_LOC (op)->etype;
1016 etype = getSpec (operandType (op));
1018 return (IN_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1021 /*------------------------------------------------------------------*/
1022 /* isOperandInDirSpace - will return true if operand is in dirSpace */
1023 /*------------------------------------------------------------------*/
1025 isOperandInDirSpace (operand * op)
1035 if (!IS_TRUE_SYMOP (op))
1038 etype = SPIL_LOC (op)->etype;
1044 etype = getSpec (operandType (op));
1046 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1049 /*--------------------------------------------------------------------*/
1050 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
1051 /*--------------------------------------------------------------------*/
1053 isOperandInCodeSpace (operand * op)
1063 etype = getSpec (operandType (op));
1065 if (!IS_TRUE_SYMOP (op))
1068 etype = SPIL_LOC (op)->etype;
1074 etype = getSpec (operandType (op));
1076 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1079 /*-----------------------------------------------------------------*/
1080 /* isOperandOnStack - will return true if operand is on stack */
1081 /*-----------------------------------------------------------------*/
1083 isOperandOnStack (operand * op)
1093 etype = getSpec (operandType (op));
1094 if (IN_STACK (etype) ||
1095 OP_SYMBOL(op)->onStack ||
1096 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1102 /*-----------------------------------------------------------------*/
1103 /* isOclsExpensive - will return true if accesses to an output */
1104 /* storage class are expensive */
1105 /*-----------------------------------------------------------------*/
1107 isOclsExpensive (struct memmap *oclass)
1109 if (port->oclsExpense)
1110 return port->oclsExpense (oclass) > 0;
1112 /* In the absence of port specific guidance, assume only */
1113 /* farspace is expensive. */
1114 return IN_FARSPACE (oclass);
1117 /*-----------------------------------------------------------------*/
1118 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1119 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1120 /*-----------------------------------------------------------------*/
1122 isiCodeInFunctionCall (iCode * ic)
1126 /* Find the next CALL/PCALL */
1129 if (lic->op == CALL || lic->op == PCALL)
1137 /* A function call was found. Scan backwards and see if an */
1138 /* IPUSH or SEND is encountered */
1141 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1143 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1151 /*-----------------------------------------------------------------*/
1152 /* operandLitValue - literal value of an operand */
1153 /*-----------------------------------------------------------------*/
1155 operandLitValue (operand * op)
1157 assert (isOperandLiteral (op));
1159 return floatFromVal (op->operand.valOperand);
1162 /*-----------------------------------------------------------------*/
1163 /* getBuiltInParms - returns parameters to a builtin functions */
1164 /*-----------------------------------------------------------------*/
1165 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1170 /* builtin functions uses only SEND for parameters */
1171 while (ic->op != CALL) {
1172 assert(ic->op == SEND && ic->builtinSEND);
1173 ic->generated = 1; /* mark the icode as generated */
1174 parms[*pcount] = IC_LEFT(ic);
1180 /* make sure this is a builtin function call */
1181 assert(IS_SYMOP(IC_LEFT(ic)));
1182 ftype = operandType(IC_LEFT(ic));
1183 assert(IFFUNC_ISBUILTIN(ftype));
1187 /*-----------------------------------------------------------------*/
1188 /* operandOperation - performs operations on operands */
1189 /*-----------------------------------------------------------------*/
1191 operandOperation (operand * left, operand * right,
1192 int op, sym_link * type)
1194 sym_link *let , *ret=NULL;
1195 operand *retval = (operand *) 0;
1197 assert (isOperandLiteral (left));
1198 let = getSpec(operandType(left));
1200 assert (isOperandLiteral (right));
1201 ret = getSpec(operandType(right));
1207 retval = operandFromValue (valCastLiteral (type,
1208 operandLitValue (left) +
1209 operandLitValue (right)));
1212 retval = operandFromValue (valCastLiteral (type,
1213 operandLitValue (left) -
1214 operandLitValue (right)));
1218 retval = operandFromValue (valCastLiteral (type,
1219 operandLitValue (left) *
1220 operandLitValue (right)));
1221 This could be all we've to do, but with gcc we've to take care about
1222 overflows. Two examples:
1223 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1224 significant bits are lost (52 in fraction, 63 bits would be
1225 necessary to keep full precision).
1226 If the resulting double value is greater than ULONG_MAX (resp.
1227 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1230 /* if it is not a specifier then we can assume that */
1231 /* it will be an unsigned long */
1232 if (IS_INT (type) ||
1235 /* long is handled here, because it can overflow with double */
1236 if (IS_LONG (type) ||
1238 /* signed and unsigned mul are the same, as long as the precision
1239 of the result isn't bigger than the precision of the operands. */
1240 retval = operandFromValue (valCastLiteral (type,
1241 (TYPE_UDWORD) operandLitValue (left) *
1242 (TYPE_UDWORD) operandLitValue (right)));
1243 else if (IS_UNSIGNED (type)) /* unsigned int */
1245 /* unsigned int is handled here in order to detect overflow */
1246 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1247 (TYPE_UWORD) operandLitValue (right);
1249 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1250 if (ul != (TYPE_UWORD) ul)
1253 else /* signed int */
1255 /* signed int is handled here in order to detect overflow */
1256 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1257 (TYPE_WORD) operandLitValue (right);
1259 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1260 if (l != (TYPE_WORD) l)
1265 /* all others go here: */
1266 retval = operandFromValue (valCastLiteral (type,
1267 operandLitValue (left) *
1268 operandLitValue (right)));
1271 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1273 werror (E_DIVIDE_BY_ZERO);
1279 if (IS_UNSIGNED (type))
1281 SPEC_USIGN (let) = 1;
1282 SPEC_USIGN (ret) = 1;
1283 retval = operandFromValue (valCastLiteral (type,
1284 (TYPE_UDWORD) operandLitValue (left) /
1285 (TYPE_UDWORD) operandLitValue (right)));
1289 retval = operandFromValue (valCastLiteral (type,
1290 operandLitValue (left) /
1291 operandLitValue (right)));
1296 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1298 werror (E_DIVIDE_BY_ZERO);
1303 if (IS_UNSIGNED (type))
1304 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1305 (TYPE_UDWORD) operandLitValue (right));
1307 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1308 (TYPE_DWORD) operandLitValue (right));
1312 /* The number of left shifts is always unsigned. Signed doesn't make
1313 sense here. Shifting by a negative number is impossible. */
1314 retval = operandFromValue (valCastLiteral (type,
1315 ((TYPE_UDWORD) operandLitValue (left) <<
1316 (TYPE_UDWORD) operandLitValue (right))));
1319 /* The number of right shifts is always unsigned. Signed doesn't make
1320 sense here. Shifting by a negative number is impossible. */
1321 if (IS_UNSIGNED(let))
1322 /* unsigned: logic shift right */
1323 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1324 (TYPE_UDWORD) operandLitValue (right));
1326 /* signed: arithmetic shift right */
1327 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1328 (TYPE_UDWORD) operandLitValue (right));
1331 if (IS_FLOAT (let) || IS_FLOAT (ret))
1333 retval = operandFromLit (operandLitValue (left) ==
1334 operandLitValue (right));
1336 else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
1338 retval = operandFromLit (operandLitValue (left) ==
1339 operandLitValue (right));
1343 /* this op doesn't care about signedness */
1346 l = (TYPE_UDWORD) operandLitValue (left);
1347 r = (TYPE_UDWORD) operandLitValue (right);
1348 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1349 neccessary to strip them to 16 bit.
1350 Literals are reduced to their cheapest type, therefore left and
1351 right might have different types. It's neccessary to find a
1352 common type: int (used for char too) or long */
1353 if (!IS_LONG (let) &&
1359 retval = operandFromLit (l == r);
1363 retval = operandFromLit (operandLitValue (left) <
1364 operandLitValue (right));
1367 retval = operandFromLit (operandLitValue (left) <=
1368 operandLitValue (right));
1371 retval = operandFromLit (operandLitValue (left) !=
1372 operandLitValue (right));
1375 retval = operandFromLit (operandLitValue (left) >
1376 operandLitValue (right));
1379 retval = operandFromLit (operandLitValue (left) >=
1380 operandLitValue (right));
1383 retval = operandFromValue (valCastLiteral (type,
1384 (TYPE_UDWORD)operandLitValue(left) &
1385 (TYPE_UDWORD)operandLitValue(right)));
1388 retval = operandFromValue (valCastLiteral (type,
1389 (TYPE_UDWORD)operandLitValue(left) |
1390 (TYPE_UDWORD)operandLitValue(right)));
1393 retval = operandFromValue (valCastLiteral (type,
1394 (TYPE_UDWORD)operandLitValue(left) ^
1395 (TYPE_UDWORD)operandLitValue(right)));
1398 retval = operandFromLit (operandLitValue (left) &&
1399 operandLitValue (right));
1402 retval = operandFromLit (operandLitValue (left) ||
1403 operandLitValue (right));
1407 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1409 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1415 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1417 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1422 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1423 (TYPE_UDWORD)operandLitValue(right)) & 1);
1426 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1427 (TYPE_UDWORD)operandLitValue(right)) & 0xFF);
1430 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1431 (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF);
1435 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1436 ((getSize (let) * 8) - 1)) & 1);
1440 retval = operandFromValue (valCastLiteral (type,
1441 -1 * operandLitValue (left)));
1445 retval = operandFromValue (valCastLiteral (type,
1447 operandLitValue (left))));
1451 retval = operandFromLit (!operandLitValue (left));
1455 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1456 " operandOperation invalid operator ");
1464 /*-----------------------------------------------------------------*/
1465 /* isOperandEqual - compares two operand & return 1 if they r = */
1466 /*-----------------------------------------------------------------*/
1468 isOperandEqual (operand * left, operand * right)
1470 /* if the pointers are equal then they are equal */
1474 /* if either of them null then false */
1475 if (!left || !right)
1478 if (left->type != right->type)
1481 if (IS_SYMOP (left) && IS_SYMOP (right))
1482 return left->key == right->key;
1484 /* if types are the same */
1488 return isSymbolEqual (left->operand.symOperand,
1489 right->operand.symOperand);
1491 return (compareType (left->operand.valOperand->type,
1492 right->operand.valOperand->type) &&
1493 (floatFromVal (left->operand.valOperand) ==
1494 floatFromVal (right->operand.valOperand)));
1496 if (compareType (left->operand.typeOperand,
1497 right->operand.typeOperand) == 1)
1504 /*-------------------------------------------------------------------*/
1505 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1506 /*-------------------------------------------------------------------*/
1508 isiCodeEqual (iCode * left, iCode * right)
1510 /* if the same pointer */
1514 /* if either of them null */
1515 if (!left || !right)
1518 /* if operand are the same */
1519 if (left->op == right->op)
1522 /* compare all the elements depending on type */
1523 if (left->op != IFX)
1525 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1527 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1533 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1535 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1537 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1546 /*-----------------------------------------------------------------*/
1547 /* newiTempFromOp - create a temp Operand with same attributes */
1548 /*-----------------------------------------------------------------*/
1550 newiTempFromOp (operand * op)
1560 nop = newiTempOperand (operandType (op), TRUE);
1561 nop->isaddr = op->isaddr;
1562 nop->isvolatile = op->isvolatile;
1563 nop->isGlobal = op->isGlobal;
1564 nop->isLiteral = op->isLiteral;
1565 nop->usesDefs = op->usesDefs;
1566 nop->isParm = op->isParm;
1570 /*-----------------------------------------------------------------*/
1571 /* operand from operand - creates an operand holder for the type */
1572 /*-----------------------------------------------------------------*/
1574 operandFromOperand (operand * op)
1580 nop = newOperand ();
1581 nop->type = op->type;
1582 nop->isaddr = op->isaddr;
1584 nop->isvolatile = op->isvolatile;
1585 nop->isGlobal = op->isGlobal;
1586 nop->isLiteral = op->isLiteral;
1587 nop->usesDefs = op->usesDefs;
1588 nop->isParm = op->isParm;
1593 nop->operand.symOperand = op->operand.symOperand;
1596 nop->operand.valOperand = op->operand.valOperand;
1599 nop->operand.typeOperand = op->operand.typeOperand;
1606 /*-----------------------------------------------------------------*/
1607 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1608 /*-----------------------------------------------------------------*/
1610 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1612 operand *nop = operandFromOperand (op);
1614 if (nop->type == SYMBOL)
1616 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1617 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1623 /*-----------------------------------------------------------------*/
1624 /* operandFromSymbol - creates an operand from a symbol */
1625 /*-----------------------------------------------------------------*/
1627 operandFromSymbol (symbol * sym)
1632 /* if the symbol's type is a literal */
1633 /* then it is an enumerator type */
1634 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1635 return operandFromValue (valFromType (sym->etype));
1638 sym->key = ++operandKey;
1640 /* if this an implicit variable, means struct/union */
1641 /* member so just return it */
1642 if (sym->implicit || IS_FUNC (sym->type))
1646 op->operand.symOperand = sym;
1648 op->isvolatile = isOperandVolatile (op, TRUE);
1649 op->isGlobal = isOperandGlobal (op);
1653 /* under the following conditions create a
1654 register equivalent for a local symbol */
1655 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1656 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1658 (!(options.model == MODEL_FLAT24)) ) &&
1659 options.stackAuto == 0)
1662 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1663 !IS_FUNC (sym->type) && /* not a function */
1664 !sym->_isparm && /* not a parameter */
1665 IS_AUTO (sym) && /* is a local auto variable */
1666 !sym->addrtaken && /* whose address has not been taken */
1667 !sym->reqv && /* does not already have a reg equivalence */
1668 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1669 !sym->islbl && /* not a label */
1670 ok /* farspace check */
1674 /* we will use it after all optimizations
1675 and before liveRange calculation */
1676 sym->reqv = newiTempOperand (sym->type, 0);
1677 sym->reqv->key = sym->key;
1678 OP_SYMBOL (sym->reqv)->prereqv = sym;
1679 OP_SYMBOL (sym->reqv)->key = sym->key;
1680 OP_SYMBOL (sym->reqv)->isreqv = 1;
1681 OP_SYMBOL (sym->reqv)->islocal = 1;
1682 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1683 SPIL_LOC (sym->reqv) = sym;
1686 if (!IS_AGGREGATE (sym->type))
1690 op->operand.symOperand = sym;
1693 op->isvolatile = isOperandVolatile (op, TRUE);
1694 op->isGlobal = isOperandGlobal (op);
1695 op->isPtr = IS_PTR (operandType (op));
1696 op->isParm = sym->_isparm;
1701 /* itemp = &[_symbol] */
1703 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1704 IC_LEFT (ic)->type = SYMBOL;
1705 IC_LEFT (ic)->operand.symOperand = sym;
1706 IC_LEFT (ic)->key = sym->key;
1707 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1708 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1709 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1712 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1713 if (IS_ARRAY (sym->type))
1715 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1716 IC_RESULT (ic)->isaddr = 0;
1719 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1723 return IC_RESULT (ic);
1726 /*-----------------------------------------------------------------*/
1727 /* operandFromValue - creates an operand from value */
1728 /*-----------------------------------------------------------------*/
1730 operandFromValue (value * val)
1734 /* if this is a symbol then do the symbol thing */
1736 return operandFromSymbol (val->sym);
1738 /* this is not a symbol */
1741 op->operand.valOperand = val;
1742 op->isLiteral = isOperandLiteral (op);
1746 /*-----------------------------------------------------------------*/
1747 /* operandFromLink - operand from typeChain */
1748 /*-----------------------------------------------------------------*/
1750 operandFromLink (sym_link * type)
1754 /* operand from sym_link */
1760 op->operand.typeOperand = copyLinkChain (type);
1764 /*-----------------------------------------------------------------*/
1765 /* operandFromLit - makes an operand from a literal value */
1766 /*-----------------------------------------------------------------*/
1768 operandFromLit (double i)
1770 return operandFromValue (valueFromLit (i));
1773 /*-----------------------------------------------------------------*/
1774 /* operandFromAst - creates an operand from an ast */
1775 /*-----------------------------------------------------------------*/
1777 operandFromAst (ast * tree,int lvl)
1783 /* depending on type do */
1787 return ast2iCode (tree,lvl+1);
1791 return operandFromValue (tree->opval.val);
1795 return operandFromLink (tree->opval.lnk);
1802 /* Just to keep the compiler happy */
1803 return (operand *) 0;
1806 /*-----------------------------------------------------------------*/
1807 /* setOperandType - sets the operand's type to the given type */
1808 /*-----------------------------------------------------------------*/
1810 setOperandType (operand * op, sym_link * type)
1812 /* depending on the type of operand */
1817 op->operand.valOperand->etype =
1818 getSpec (op->operand.valOperand->type =
1819 copyLinkChain (type));
1823 if (op->operand.symOperand->isitmp)
1824 op->operand.symOperand->etype =
1825 getSpec (op->operand.symOperand->type =
1826 copyLinkChain (type));
1828 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1829 "attempt to modify type of source");
1833 op->operand.typeOperand = copyLinkChain (type);
1839 /*-----------------------------------------------------------------*/
1840 /* Get size in byte of ptr need to access an array */
1841 /*-----------------------------------------------------------------*/
1843 getArraySizePtr (operand * op)
1845 sym_link *ltype = operandType(op);
1849 int size = getSize(ltype);
1850 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1855 sym_link *letype = getSpec(ltype);
1856 switch (PTR_TYPE (SPEC_OCLS (letype)))
1868 if (GPTRSIZE > FPTRSIZE)
1869 return (GPTRSIZE-1);
1880 /*-----------------------------------------------------------------*/
1881 /* perform "usual unary conversions" */
1882 /*-----------------------------------------------------------------*/
1885 usualUnaryConversions (operand * op)
1887 if (IS_INTEGRAL (operandType (op)))
1889 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1892 return geniCodeCast (INTTYPE, op, TRUE);
1899 /*-----------------------------------------------------------------*/
1900 /* perform "usual binary conversions" */
1901 /*-----------------------------------------------------------------*/
1904 usualBinaryConversions (operand ** op1, operand ** op2,
1905 RESULT_TYPE resultType, int op)
1908 sym_link *rtype = operandType (*op2);
1909 sym_link *ltype = operandType (*op1);
1911 ctype = computeType (ltype, rtype, resultType, op);
1918 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1920 /* one byte operations: keep signedness for code generator */
1928 *op1 = geniCodeCast (ctype, *op1, TRUE);
1929 *op2 = geniCodeCast (ctype, *op2, TRUE);
1934 /*-----------------------------------------------------------------*/
1935 /* geniCodeValueAtAddress - generate intermeditate code for value */
1937 /*-----------------------------------------------------------------*/
1939 geniCodeRValue (operand * op, bool force)
1942 sym_link *type = operandType (op);
1943 sym_link *etype = getSpec (type);
1945 /* if this is an array & already */
1946 /* an address then return this */
1947 if (IS_AGGREGATE (type) ||
1948 (IS_PTR (type) && !force && !op->isaddr))
1949 return operandFromOperand (op);
1951 /* if this is not an address then must be */
1952 /* rvalue already so return this one */
1956 /* if this is not a temp symbol then */
1957 if (!IS_ITEMP (op) &&
1959 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1961 op = operandFromOperand (op);
1966 if (IS_SPEC (type) &&
1967 IS_TRUE_SYMOP (op) &&
1968 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1969 (options.model == MODEL_FLAT24) ))
1971 op = operandFromOperand (op);
1976 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1977 if (IS_PTR (type) && op->isaddr && force)
1980 type = copyLinkChain (type);
1982 IC_RESULT (ic) = newiTempOperand (type, 1);
1983 IC_RESULT (ic)->isaddr = 0;
1985 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1989 return IC_RESULT (ic);
1992 /*-----------------------------------------------------------------*/
1993 /* geniCodeCast - changes the value from one type to another */
1994 /*-----------------------------------------------------------------*/
1996 geniCodeCast (sym_link * type, operand * op, bool implicit)
2000 sym_link *opetype = getSpec (optype = operandType (op));
2004 /* one of them has size zero then error */
2005 if (IS_VOID (optype))
2007 werror (E_CAST_ZERO);
2011 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
2013 geniCodeArray2Ptr (op);
2017 /* if the operand is already the desired type then do nothing */
2018 if (compareType (type, optype) == 1)
2021 /* if this is a literal then just change the type & return */
2022 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
2024 return operandFromValue (valCastLiteral (type,
2025 operandLitValue (op)));
2028 /* if casting to/from pointers, do some checking */
2029 if (IS_PTR(type)) { // to a pointer
2030 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
2031 if (IS_INTEGRAL(optype)) {
2032 // maybe this is NULL, than it's ok.
2033 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
2034 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
2035 // no way to set the storage
2036 if (IS_LITERAL(optype)) {
2037 werror(E_LITERAL_GENERIC);
2040 werror(E_NONPTR2_GENPTR);
2043 } else if (implicit) {
2044 werror(W_INTEGRAL2PTR_NOCAST);
2049 // shouldn't do that with float, array or structure unless to void
2050 if (!IS_VOID(getSpec(type)) &&
2051 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2052 werror(E_INCOMPAT_TYPES);
2056 } else { // from a pointer to a pointer
2057 if (IS_GENPTR(type) && IS_VOID(type->next))
2058 { // cast to void* is always allowed
2060 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2061 { // cast from void* is always allowed
2063 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2064 // if not a pointer to a function
2065 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2066 if (implicit) { // if not to generic, they have to match
2067 if (!IS_GENPTR(type) &&
2068 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2069 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2073 werror(E_INCOMPAT_PTYPES);
2080 } else { // to a non pointer
2081 if (IS_PTR(optype)) { // from a pointer
2082 if (implicit) { // sneaky
2083 if (IS_INTEGRAL(type)) {
2084 werror(W_PTR2INTEGRAL_NOCAST);
2086 } else { // shouldn't do that with float, array or structure
2087 werror(E_INCOMPAT_TYPES);
2094 printFromToType (optype, type);
2097 /* if they are the same size create an assignment */
2099 /* This seems very dangerous to me, since there are several */
2100 /* optimizations (for example, gcse) that don't notice the */
2101 /* cast hidden in this assignement and may simplify an */
2102 /* iCode to use the original (uncasted) operand. */
2103 /* Unfortunately, other things break when this cast is */
2104 /* made explicit. Need to fix this someday. */
2105 /* -- EEP, 2004/01/21 */
2106 if (getSize (type) == getSize (optype) &&
2107 !IS_BITFIELD (type) &&
2109 !IS_FLOAT (optype) &&
2111 !IS_FIXED (optype) &&
2112 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2113 (!IS_SPEC (type) && !IS_SPEC (optype))))
2115 ic = newiCode ('=', NULL, op);
2116 IC_RESULT (ic) = newiTempOperand (type, 0);
2117 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2118 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2119 IC_RESULT (ic)->isaddr = 0;
2123 ic = newiCode (CAST, operandFromLink (type),
2124 geniCodeRValue (op, FALSE));
2126 IC_RESULT (ic) = newiTempOperand (type, 0);
2129 /* preserve the storage class & output class */
2130 /* of the original variable */
2131 restype = getSpec (operandType (IC_RESULT (ic)));
2132 if (!IS_LITERAL(opetype) &&
2135 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2136 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2139 return IC_RESULT (ic);
2142 /*-----------------------------------------------------------------*/
2143 /* geniCodeLabel - will create a Label */
2144 /*-----------------------------------------------------------------*/
2146 geniCodeLabel (symbol * label)
2150 ic = newiCodeLabelGoto (LABEL, label);
2154 /*-----------------------------------------------------------------*/
2155 /* geniCodeGoto - will create a Goto */
2156 /*-----------------------------------------------------------------*/
2158 geniCodeGoto (symbol * label)
2162 ic = newiCodeLabelGoto (GOTO, label);
2166 /*-----------------------------------------------------------------*/
2167 /* geniCodeMultiply - gen intermediate code for multiplication */
2168 /*-----------------------------------------------------------------*/
2170 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2177 /* if they are both literal then we know the result */
2178 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2179 return operandFromValue (valMult (left->operand.valOperand,
2180 right->operand.valOperand));
2182 if (IS_LITERAL(retype)) {
2183 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2186 resType = usualBinaryConversions (&left, &right, resultType, '*');
2188 rtype = operandType (right);
2189 retype = getSpec (rtype);
2190 ltype = operandType (left);
2191 letype = getSpec (ltype);
2194 /* if the right is a literal & power of 2 */
2195 /* then make it a left shift */
2196 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2197 efficient in most cases than 2 bytes result = 2 bytes << literal
2198 if port has 1 byte muldiv */
2199 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2200 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2201 && (port->support.muldiv == 1))
2202 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2203 && strcmp (port->target, "pic14") != 0)
2205 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2207 /* LEFT_OP need same size for left and result, */
2208 left = geniCodeCast (resType, left, TRUE);
2209 ltype = operandType (left);
2211 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2215 ic = newiCode ('*', left, right); /* normal multiplication */
2216 /* if the size left or right > 1 then support routine */
2217 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2221 IC_RESULT (ic) = newiTempOperand (resType, 1);
2224 return IC_RESULT (ic);
2227 /*-----------------------------------------------------------------*/
2228 /* geniCodeDivision - gen intermediate code for division */
2229 /*-----------------------------------------------------------------*/
2231 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2236 sym_link *rtype = operandType (right);
2237 sym_link *retype = getSpec (rtype);
2238 sym_link *ltype = operandType (left);
2239 sym_link *letype = getSpec (ltype);
2241 resType = usualBinaryConversions (&left, &right, resultType, '/');
2243 /* if the right is a literal & power of 2
2244 and left is unsigned then make it a
2246 if (IS_LITERAL (retype) &&
2247 !IS_FLOAT (letype) &&
2248 !IS_FIXED (letype) &&
2249 IS_UNSIGNED(letype) &&
2250 ((p2 = powof2 ((TYPE_UDWORD)
2251 floatFromVal (right->operand.valOperand))) > 0)) {
2252 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2256 ic = newiCode ('/', left, right); /* normal division */
2257 /* if the size left or right > 1 then support routine */
2258 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2261 IC_RESULT (ic) = newiTempOperand (resType, 0);
2264 return IC_RESULT (ic);
2266 /*-----------------------------------------------------------------*/
2267 /* geniCodeModulus - gen intermediate code for modulus */
2268 /*-----------------------------------------------------------------*/
2270 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2276 /* if they are both literal then we know the result */
2277 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2278 return operandFromValue (valMod (left->operand.valOperand,
2279 right->operand.valOperand));
2281 resType = usualBinaryConversions (&left, &right, resultType, '%');
2283 /* now they are the same size */
2284 ic = newiCode ('%', left, right);
2286 /* if the size left or right > 1 then support routine */
2287 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2289 IC_RESULT (ic) = newiTempOperand (resType, 0);
2292 return IC_RESULT (ic);
2295 /*-----------------------------------------------------------------*/
2296 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2297 /*-----------------------------------------------------------------*/
2299 geniCodePtrPtrSubtract (operand * left, operand * right)
2305 /* if they are both literals then */
2306 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2308 result = operandFromValue (valMinus (left->operand.valOperand,
2309 right->operand.valOperand));
2313 ic = newiCode ('-', left, right);
2315 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2319 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2323 // should we really do this? is this ANSI?
2324 return geniCodeDivision (result,
2325 operandFromLit (getSize (ltype->next)),
2329 /*-----------------------------------------------------------------*/
2330 /* geniCodeSubtract - generates code for subtraction */
2331 /*-----------------------------------------------------------------*/
2333 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2340 /* if they both pointers then */
2341 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2342 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2343 return geniCodePtrPtrSubtract (left, right);
2345 /* if they are both literal then we know the result */
2346 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2347 && left->isLiteral && right->isLiteral)
2348 return operandFromValue (valMinus (left->operand.valOperand,
2349 right->operand.valOperand));
2351 /* if left is an array or pointer */
2352 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2354 isarray = left->isaddr;
2355 right = geniCodeMultiply (right,
2356 operandFromLit (getSize (ltype->next)),
2357 (getArraySizePtr(left) >= INTSIZE) ?
2360 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2363 { /* make them the same size */
2364 resType = usualBinaryConversions (&left, &right, resultType, '-');
2367 ic = newiCode ('-', left, right);
2369 IC_RESULT (ic) = newiTempOperand (resType, 1);
2370 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2372 /* if left or right is a float */
2373 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2374 || IS_FIXED (ltype) || IS_FIXED (rtype))
2378 return IC_RESULT (ic);
2381 /*-----------------------------------------------------------------*/
2382 /* geniCodeAdd - generates iCode for addition */
2383 /*-----------------------------------------------------------------*/
2385 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2394 /* if the right side is LITERAL zero */
2395 /* return the left side */
2396 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2399 /* if left is literal zero return right */
2400 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2403 /* if left is a pointer then size */
2404 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2406 isarray = left->isaddr;
2407 // there is no need to multiply with 1
2408 if (getSize (ltype->next) != 1)
2410 size = operandFromLit (getSize (ltype->next));
2411 SPEC_USIGN (getSpec (operandType (size))) = 1;
2412 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2413 right = geniCodeMultiply (right, size, resultType);
2414 /* Even if right is a 'unsigned char',
2415 the result will be a 'signed int' due to the promotion rules.
2416 It doesn't make sense when accessing arrays, so let's fix it here: */
2418 SPEC_USIGN (getSpec (operandType (right))) = 1;
2420 resType = copyLinkChain (ltype);
2423 { // make them the same size
2424 resType = usualBinaryConversions (&left, &right, resultType, '+');
2427 /* if they are both literals then we know */
2428 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2429 && left->isLiteral && right->isLiteral)
2430 return operandFromValue (valPlus (valFromType (ltype),
2431 valFromType (rtype)));
2433 ic = newiCode ('+', left, right);
2435 IC_RESULT (ic) = newiTempOperand (resType, 1);
2436 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2438 /* if left or right is a float then support
2440 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2441 || IS_FIXED (ltype) || IS_FIXED (rtype))
2446 return IC_RESULT (ic);
2450 /*-----------------------------------------------------------------*/
2451 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2452 /*-----------------------------------------------------------------*/
2454 aggrToPtr (sym_link * type, bool force)
2459 if (IS_PTR (type) && !force)
2462 etype = getSpec (type);
2463 ptype = newLink (DECLARATOR);
2467 /* set the pointer depending on the storage class */
2468 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2472 /*------------------------------------------------------------------*/
2473 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2474 /*------------------------------------------------------------------*/
2476 aggrToPtrDclType (sym_link * type, bool force)
2478 if (IS_PTR (type) && !force)
2479 return DCL_TYPE (type);
2481 /* return the pointer depending on the storage class */
2482 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2485 /*-----------------------------------------------------------------*/
2486 /* geniCodeArray2Ptr - array to pointer */
2487 /*-----------------------------------------------------------------*/
2489 geniCodeArray2Ptr (operand * op)
2491 sym_link *optype = operandType (op);
2492 sym_link *opetype = getSpec (optype);
2494 /* set the pointer depending on the storage class */
2495 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2502 /*-----------------------------------------------------------------*/
2503 /* geniCodeArray - array access */
2504 /*-----------------------------------------------------------------*/
2506 geniCodeArray (operand * left, operand * right, int lvl)
2510 sym_link *ltype = operandType (left);
2512 RESULT_TYPE resultType;
2514 resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2515 if (DCL_ELEM (ltype))
2517 if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2518 resultType = RESULT_TYPE_CHAR;
2523 if (IS_PTR (ltype->next) && left->isaddr)
2525 left = geniCodeRValue (left, FALSE);
2528 return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2531 size = operandFromLit (getSize (ltype->next));
2532 SPEC_USIGN (getSpec (operandType (size))) = 1;
2533 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2534 right = geniCodeMultiply (right, size, resultType);
2535 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2536 It doesn't make sense when accessing arrays, so let's fix it here: */
2538 SPEC_USIGN (getSpec (operandType (right))) = 1;
2539 /* we can check for limits here */
2540 /* already done in SDCCast.c
2541 if (isOperandLiteral (right) &&
2544 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2546 werror (W_IDX_OUT_OF_BOUNDS,
2547 (int) operandLitValue (right) / getSize (ltype->next),
2552 ic = newiCode ('+', left, right);
2554 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2555 !IS_AGGREGATE (ltype->next) &&
2556 !IS_PTR (ltype->next))
2557 ? ltype : ltype->next), 0);
2559 if (!IS_AGGREGATE (ltype->next))
2561 IC_RESULT (ic)->isaddr = 1;
2562 IC_RESULT (ic)->aggr2ptr = 1;
2566 return IC_RESULT (ic);
2569 /*-----------------------------------------------------------------*/
2570 /* geniCodeStruct - generates intermediate code for structures */
2571 /*-----------------------------------------------------------------*/
2573 geniCodeStruct (operand * left, operand * right, bool islval)
2576 sym_link *type = operandType (left);
2577 sym_link *etype = getSpec (type);
2579 symbol *element = getStructElement (SPEC_STRUCT (etype),
2580 right->operand.symOperand);
2582 wassert(IS_SYMOP(right));
2584 /* add the offset */
2585 ic = newiCode ('+', left, operandFromLit (element->offset));
2587 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2589 /* preserve the storage & output class of the struct */
2590 /* as well as the volatile attribute */
2591 retype = getSpec (operandType (IC_RESULT (ic)));
2592 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2593 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2594 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2595 SPEC_CONST (retype) |= SPEC_CONST (etype);
2597 if (IS_PTR (element->type))
2598 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2600 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2603 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2606 /*-----------------------------------------------------------------*/
2607 /* geniCodePostInc - generate int code for Post increment */
2608 /*-----------------------------------------------------------------*/
2610 geniCodePostInc (operand * op)
2614 sym_link *optype = operandType (op);
2616 operand *rv = (IS_ITEMP (op) ?
2617 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2619 sym_link *rvtype = operandType (rv);
2622 /* if this is not an address we have trouble */
2625 werror (E_LVALUE_REQUIRED, "++");
2629 rOp = newiTempOperand (rvtype, 0);
2630 OP_SYMBOL(rOp)->noSpilLoc = 1;
2633 OP_SYMBOL(rv)->noSpilLoc = 1;
2635 geniCodeAssign (rOp, rv, 0, 0);
2637 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2639 werror(W_SIZEOF_VOID);
2640 if (IS_FLOAT (rvtype))
2641 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2642 else if (IS_FIXED16X16 (rvtype))
2643 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2645 ic = newiCode ('+', rv, operandFromLit (size));
2647 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2650 geniCodeAssign (op, result, 0, 0);
2656 /*-----------------------------------------------------------------*/
2657 /* geniCodePreInc - generate code for preIncrement */
2658 /*-----------------------------------------------------------------*/
2660 geniCodePreInc (operand * op, bool lvalue)
2663 sym_link *optype = operandType (op);
2664 operand *rop = (IS_ITEMP (op) ?
2665 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2667 sym_link *roptype = operandType (rop);
2673 werror (E_LVALUE_REQUIRED, "++");
2677 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2679 werror(W_SIZEOF_VOID);
2680 if (IS_FLOAT (roptype))
2681 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2682 else if (IS_FIXED16X16 (roptype))
2683 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2685 ic = newiCode ('+', rop, operandFromLit (size));
2686 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2689 (void) geniCodeAssign (op, result, 0, 0);
2690 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2696 /*-----------------------------------------------------------------*/
2697 /* geniCodePostDec - generates code for Post decrement */
2698 /*-----------------------------------------------------------------*/
2700 geniCodePostDec (operand * op)
2704 sym_link *optype = operandType (op);
2706 operand *rv = (IS_ITEMP (op) ?
2707 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2709 sym_link *rvtype = operandType (rv);
2712 /* if this is not an address we have trouble */
2715 werror (E_LVALUE_REQUIRED, "--");
2719 rOp = newiTempOperand (rvtype, 0);
2720 OP_SYMBOL(rOp)->noSpilLoc = 1;
2723 OP_SYMBOL(rv)->noSpilLoc = 1;
2725 geniCodeAssign (rOp, rv, 0, 0);
2727 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2729 werror(W_SIZEOF_VOID);
2730 if (IS_FLOAT (rvtype))
2731 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2732 else if (IS_FIXED16X16 (rvtype))
2733 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2735 ic = newiCode ('-', rv, operandFromLit (size));
2737 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2740 geniCodeAssign (op, result, 0, 0);
2746 /*-----------------------------------------------------------------*/
2747 /* geniCodePreDec - generate code for pre decrement */
2748 /*-----------------------------------------------------------------*/
2750 geniCodePreDec (operand * op, bool lvalue)
2753 sym_link *optype = operandType (op);
2754 operand *rop = (IS_ITEMP (op) ?
2755 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2757 sym_link *roptype = operandType (rop);
2763 werror (E_LVALUE_REQUIRED, "--");
2767 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2769 werror(W_SIZEOF_VOID);
2770 if (IS_FLOAT (roptype))
2771 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2772 else if (IS_FIXED16X16 (roptype))
2773 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2775 ic = newiCode ('-', rop, operandFromLit (size));
2776 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2779 (void) geniCodeAssign (op, result, 0, 0);
2780 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2787 /*-----------------------------------------------------------------*/
2788 /* geniCodeBitwise - gen int code for bitWise operators */
2789 /*-----------------------------------------------------------------*/
2791 geniCodeBitwise (operand * left, operand * right,
2792 int oper, sym_link * resType)
2796 left = geniCodeCast (resType, left, TRUE);
2797 right = geniCodeCast (resType, right, TRUE);
2799 ic = newiCode (oper, left, right);
2800 IC_RESULT (ic) = newiTempOperand (resType, 0);
2803 return IC_RESULT (ic);
2806 /*-----------------------------------------------------------------*/
2807 /* geniCodeAddressOf - gens icode for '&' address of operator */
2808 /*-----------------------------------------------------------------*/
2810 geniCodeAddressOf (operand * op)
2814 sym_link *optype = operandType (op);
2815 sym_link *opetype = getSpec (optype);
2817 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2819 op = operandFromOperand (op);
2824 /* lvalue check already done in decorateType */
2825 /* this must be a lvalue */
2826 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2827 /* werror (E_LVALUE_REQUIRED,"&"); */
2831 p = newLink (DECLARATOR);
2833 /* set the pointer depending on the storage class */
2834 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2836 p->next = copyLinkChain (optype);
2838 /* if already a temp */
2841 setOperandType (op, p);
2846 /* other wise make this of the type coming in */
2847 ic = newiCode (ADDRESS_OF, op, NULL);
2848 IC_RESULT (ic) = newiTempOperand (p, 1);
2849 IC_RESULT (ic)->isaddr = 0;
2851 return IC_RESULT (ic);
2854 /*-----------------------------------------------------------------*/
2855 /* setOClass - sets the output class depending on the pointer type */
2856 /*-----------------------------------------------------------------*/
2858 setOClass (sym_link * ptr, sym_link * spec)
2860 switch (DCL_TYPE (ptr))
2863 SPEC_OCLS (spec) = data;
2867 SPEC_OCLS (spec) = generic;
2871 SPEC_OCLS (spec) = xdata;
2875 SPEC_OCLS (spec) = code;
2879 SPEC_OCLS (spec) = idata;
2883 SPEC_OCLS (spec) = xstack;
2887 SPEC_OCLS (spec) = eeprom;
2896 /*-----------------------------------------------------------------*/
2897 /* geniCodeDerefPtr - dereference pointer with '*' */
2898 /*-----------------------------------------------------------------*/
2900 geniCodeDerefPtr (operand * op,int lvl)
2902 sym_link *rtype, *retype;
2903 sym_link *optype = operandType (op);
2905 // if this is an array then array access
2906 if (IS_ARRAY (optype)) {
2907 // don't worry, this will be optimized out later
2908 return geniCodeArray (op, operandFromLit (0), lvl);
2911 // just in case someone screws up
2912 wassert (IS_PTR (optype));
2914 if (IS_TRUE_SYMOP (op))
2917 op = geniCodeRValue (op, TRUE);
2920 /* now get rid of the pointer part */
2921 if (isLvaluereq(lvl) && IS_ITEMP (op))
2923 retype = getSpec (rtype = copyLinkChain (optype));
2927 retype = getSpec (rtype = copyLinkChain (optype->next));
2928 /* outputclass needs 2b updated */
2929 setOClass (optype, retype);
2932 op->isGptr = IS_GENPTR (optype);
2934 op->isaddr = (IS_PTR (rtype) ||
2935 IS_STRUCT (rtype) ||
2941 if (!isLvaluereq(lvl))
2942 op = geniCodeRValue (op, TRUE);
2944 setOperandType (op, rtype);
2949 /*-----------------------------------------------------------------*/
2950 /* geniCodeUnaryMinus - does a unary minus of the operand */
2951 /*-----------------------------------------------------------------*/
2953 geniCodeUnaryMinus (operand * op)
2956 sym_link *optype = operandType (op);
2958 if (IS_LITERAL (optype))
2959 return operandFromLit (-floatFromVal (op->operand.valOperand));
2961 ic = newiCode (UNARYMINUS, op, NULL);
2962 IC_RESULT (ic) = newiTempOperand (optype, 0);
2964 return IC_RESULT (ic);
2967 /*-----------------------------------------------------------------*/
2968 /* geniCodeLeftShift - gen i code for left shift */
2969 /*-----------------------------------------------------------------*/
2971 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2976 ic = newiCode (LEFT_OP, left, right);
2978 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2979 IC_RESULT (ic) = newiTempOperand (resType, 0);
2981 return IC_RESULT (ic);
2984 /*-----------------------------------------------------------------*/
2985 /* geniCodeRightShift - gen i code for right shift */
2986 /*-----------------------------------------------------------------*/
2988 geniCodeRightShift (operand * left, operand * right)
2992 ic = newiCode (RIGHT_OP, left, right);
2993 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2995 return IC_RESULT (ic);
2998 /*-----------------------------------------------------------------*/
2999 /* geniCodeLogic- logic code */
3000 /*-----------------------------------------------------------------*/
3002 geniCodeLogic (operand * left, operand * right, int op)
3006 sym_link *rtype = operandType (right);
3007 sym_link *ltype = operandType (left);
3009 /* left is integral type and right is literal then
3010 check if the literal value is within bounds */
3011 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3013 checkConstantRange(ltype,
3014 OP_VALUE(right), "compare operation", 1);
3017 /* if one operand is a pointer and the other is a literal generic void pointer,
3018 change the type of the literal generic void pointer to match the other pointer */
3019 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3020 && IS_PTR (rtype) && !IS_GENPTR(rtype))
3022 /* find left's definition */
3023 ic = (iCode *) setFirstItem (iCodeChain);
3026 if (((ic->op == CAST) || (ic->op == '='))
3027 && isOperandEqual(left, IC_RESULT (ic)))
3030 ic = setNextItem (iCodeChain);
3032 /* if casting literal to generic pointer, then cast to rtype instead */
3033 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3035 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3036 ltype = operandType(left);
3039 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3040 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3042 /* find right's definition */
3043 ic = (iCode *) setFirstItem (iCodeChain);
3046 if (((ic->op == CAST) || (ic->op == '='))
3047 && isOperandEqual(right, IC_RESULT (ic)))
3050 ic = setNextItem (iCodeChain);
3052 /* if casting literal to generic pointer, then cast to rtype instead */
3053 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3055 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3056 rtype = operandType(right);
3060 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3062 ic = newiCode (op, left, right);
3063 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3065 /* if comparing float
3066 and not a '==' || '!=' || '&&' || '||' (these
3068 if (IS_FLOAT(ctype) &&
3075 /* if comparing a fixed type use support functions */
3076 if (IS_FIXED(ctype))
3080 return IC_RESULT (ic);
3083 /*-----------------------------------------------------------------*/
3084 /* geniCodeLogicAndOr - && || operations */
3085 /*-----------------------------------------------------------------*/
3087 geniCodeLogicAndOr (ast *tree, int lvl)
3091 symbol *falseLabel = newiTempLabel (NULL);
3092 symbol *trueLabel = newiTempLabel (NULL);
3093 symbol *exitLabel = newiTempLabel (NULL);
3094 operand *op, *result, *condition;
3096 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3097 They can be reenabled by executing the following block. If you find
3098 a decent optimization you could start right here:
3103 operand *leftOp, *rightOp;
3105 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3106 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3108 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3112 /* generate two IFX for the '&&' or '||' op */
3114 /* evaluate left operand */
3115 condition = ast2iCode (tree->left, lvl + 1);
3116 op = geniCodeRValue (condition, FALSE);
3118 /* test left operand */
3119 if (tree->opval.op == AND_OP)
3120 ic = newiCodeCondition (op, NULL, falseLabel);
3122 ic = newiCodeCondition (op, trueLabel, NULL);
3125 /* evaluate right operand */
3126 condition = ast2iCode (tree->right, lvl + 1);
3127 op = geniCodeRValue (condition, FALSE);
3129 /* test right operand */
3130 ic = newiCodeCondition (op, trueLabel, NULL);
3133 /* store 0 or 1 in result */
3134 type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3135 result = newiTempOperand (type, 1);
3137 geniCodeLabel (falseLabel);
3138 geniCodeAssign (result, operandFromLit (0), 0, 0);
3139 /* generate an unconditional goto */
3140 geniCodeGoto (exitLabel);
3142 geniCodeLabel (trueLabel);
3143 geniCodeAssign (result, operandFromLit (1), 0, 0);
3145 geniCodeLabel (exitLabel);
3150 /*-----------------------------------------------------------------*/
3151 /* geniCodeUnary - for a generic unary operation */
3152 /*-----------------------------------------------------------------*/
3154 geniCodeUnary (operand * op, int oper)
3156 iCode *ic = newiCode (oper, op, NULL);
3158 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3160 return IC_RESULT (ic);
3163 /*-----------------------------------------------------------------*/
3164 /* geniCodeBinary - for a generic binary operation */
3165 /*-----------------------------------------------------------------*/
3167 geniCodeBinary (operand * left, operand * right, int oper)
3169 iCode *ic = newiCode (oper, left, right);
3171 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3173 return IC_RESULT (ic);
3176 /*-----------------------------------------------------------------*/
3177 /* geniCodeConditional - geniCode for '?' ':' operation */
3178 /*-----------------------------------------------------------------*/
3180 geniCodeConditional (ast * tree,int lvl)
3183 symbol *falseLabel = newiTempLabel (NULL);
3184 symbol *exitLabel = newiTempLabel (NULL);
3185 operand *cond = ast2iCode (tree->left,lvl+1);
3186 operand *true, *false, *result;
3188 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3192 true = ast2iCode (tree->right->left,lvl+1);
3194 /* move the value to a new Operand */
3195 result = newiTempOperand (tree->right->ftype, 0);
3196 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3198 /* generate an unconditional goto */
3199 geniCodeGoto (exitLabel);
3201 /* now for the right side */
3202 geniCodeLabel (falseLabel);
3204 false = ast2iCode (tree->right->right,lvl+1);
3205 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3207 /* create the exit label */
3208 geniCodeLabel (exitLabel);
3213 /*-----------------------------------------------------------------*/
3214 /* geniCodeAssign - generate code for assignment */
3215 /*-----------------------------------------------------------------*/
3217 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3220 sym_link *ltype = operandType (left);
3221 sym_link *rtype = operandType (right);
3223 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3225 werror (E_LVALUE_REQUIRED, "assignment");
3229 /* left is integral type and right is literal then
3230 check if the literal value is within bounds */
3231 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3233 checkConstantRange(ltype,
3234 OP_VALUE(right), "= operation", 0);
3237 /* if the left & right type don't exactly match */
3238 /* if pointer set then make sure the check is
3239 done with the type & not the pointer */
3240 /* then cast rights type to left */
3242 /* first check the type for pointer assignement */
3243 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3244 compareType (ltype, rtype) <= 0)
3246 if (compareType (ltype->next, rtype) < 0)
3247 right = geniCodeCast (ltype->next, right, TRUE);
3249 else if (compareType (ltype, rtype) < 0)
3250 right = geniCodeCast (ltype, right, TRUE);
3252 /* If left is a true symbol & ! volatile
3253 create an assignment to temporary for
3254 the right & then assign this temporary
3255 to the symbol. This is SSA (static single
3256 assignment). Isn't it simple and folks have
3257 published mountains of paper on it */
3258 if (IS_TRUE_SYMOP (left) &&
3259 !isOperandVolatile (left, FALSE) &&
3260 isOperandGlobal (left))
3265 if (IS_TRUE_SYMOP (right))
3266 sym = OP_SYMBOL (right);
3267 ic = newiCode ('=', NULL, right);
3268 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3269 /* avoid double fetch from volatile right, see bug 1369874 */
3270 if (!isOperandVolatile (right, FALSE))
3271 SPIL_LOC (newRight) = sym;
3276 ic = newiCode ('=', NULL, right);
3277 IC_RESULT (ic) = left;
3280 /* if left isgptr flag is set then support
3281 routine will be required */
3285 ic->nosupdate = nosupdate;
3289 /*-----------------------------------------------------------------*/
3290 /* geniCodeDummyRead - generate code for dummy read */
3291 /*-----------------------------------------------------------------*/
3293 geniCodeDummyRead (operand * op)
3296 sym_link *type = operandType (op);
3298 if (!IS_VOLATILE(type))
3301 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3307 /*-----------------------------------------------------------------*/
3308 /* geniCodeSEParms - generate code for side effecting fcalls */
3309 /*-----------------------------------------------------------------*/
3311 geniCodeSEParms (ast * parms,int lvl)
3316 if (parms->type == EX_OP && parms->opval.op == PARAM)
3318 geniCodeSEParms (parms->left,lvl);
3319 geniCodeSEParms (parms->right,lvl);
3323 /* hack don't like this but too lazy to think of
3325 if (IS_ADDRESS_OF_OP (parms))
3326 parms->left->lvalue = 1;
3328 if (IS_CAST_OP (parms) &&
3329 IS_PTR (parms->ftype) &&
3330 IS_ADDRESS_OF_OP (parms->right))
3331 parms->right->left->lvalue = 1;
3333 parms->opval.oprnd =
3334 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3336 parms->type = EX_OPERAND;
3337 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3338 SPEC_ARGREG(parms->ftype);
3341 /*-----------------------------------------------------------------*/
3342 /* geniCodeParms - generates parameters */
3343 /*-----------------------------------------------------------------*/
3345 geniCodeParms (ast * parms, value *argVals, int *stack,
3346 sym_link * ftype, int lvl)
3354 if (argVals==NULL) {
3356 argVals = FUNC_ARGS (ftype);
3359 /* if this is a param node then do the left & right */
3360 if (parms->type == EX_OP && parms->opval.op == PARAM)
3362 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3363 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3367 /* get the parameter value */
3368 if (parms->type == EX_OPERAND)
3369 pval = parms->opval.oprnd;
3372 /* maybe this else should go away ?? */
3373 /* hack don't like this but too lazy to think of
3375 if (IS_ADDRESS_OF_OP (parms))
3376 parms->left->lvalue = 1;
3378 if (IS_CAST_OP (parms) &&
3379 IS_PTR (parms->ftype) &&
3380 IS_ADDRESS_OF_OP (parms->right))
3381 parms->right->left->lvalue = 1;
3383 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3386 /* if register parm then make it a send */
3387 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3388 IFFUNC_ISBUILTIN(ftype))
3390 ic = newiCode (SEND, pval, NULL);
3391 ic->argreg = SPEC_ARGREG(parms->etype);
3392 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3397 /* now decide whether to push or assign */
3398 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3402 operand *top = operandFromSymbol (argVals->sym);
3403 /* clear useDef and other bitVectors */
3404 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3405 geniCodeAssign (top, pval, 1, 0);
3409 sym_link *p = operandType (pval);
3411 ic = newiCode (IPUSH, pval, NULL);
3413 /* update the stack adjustment */
3414 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3419 argVals=argVals->next;
3423 /*-----------------------------------------------------------------*/
3424 /* geniCodeCall - generates temp code for calling */
3425 /*-----------------------------------------------------------------*/
3427 geniCodeCall (operand * left, ast * parms,int lvl)
3431 sym_link *type, *etype;
3435 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3436 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3437 werror (E_FUNCTION_EXPECTED);
3438 return operandFromValue(valueFromLit(0));
3441 /* take care of parameters with side-effecting
3442 function calls in them, this is required to take care
3443 of overlaying function parameters */
3444 geniCodeSEParms (parms,lvl);
3446 ftype = operandType (left);
3447 if (IS_FUNCPTR (ftype))
3448 ftype = ftype->next;
3450 /* first the parameters */
3451 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3453 /* now call : if symbol then pcall */
3454 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3455 ic = newiCode (PCALL, left, NULL);
3457 ic = newiCode (CALL, left, NULL);
3460 type = copyLinkChain (ftype->next);
3461 etype = getSpec (type);
3462 SPEC_EXTR (etype) = 0;
3463 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3467 /* stack adjustment after call */
3468 ic->parmBytes = stack;
3473 /*-----------------------------------------------------------------*/
3474 /* geniCodeReceive - generate intermediate code for "receive" */
3475 /*-----------------------------------------------------------------*/
3477 geniCodeReceive (value * args, operand * func)
3479 unsigned char paramByteCounter = 0;
3481 /* for all arguments that are passed in registers */
3484 if (IS_REGPARM (args->etype))
3486 operand *opr = operandFromValue (args);
3488 symbol *sym = OP_SYMBOL (opr);
3491 /* we will use it after all optimizations
3492 and before liveRange calculation */
3493 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3496 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3497 options.stackAuto == 0 &&
3498 (!(options.model == MODEL_FLAT24)) )
3503 opl = newiTempOperand (args->type, 0);
3505 sym->reqv->key = sym->key;
3506 OP_SYMBOL (sym->reqv)->key = sym->key;
3507 OP_SYMBOL (sym->reqv)->isreqv = 1;
3508 OP_SYMBOL (sym->reqv)->islocal = 0;
3509 SPIL_LOC (sym->reqv) = sym;
3513 ic = newiCode (RECEIVE, func, NULL);
3514 ic->argreg = SPEC_ARGREG(args->etype);
3515 if (ic->argreg == 1) {
3516 currFunc->recvSize = getSize (sym->type);
3518 IC_RESULT (ic) = opr;
3520 /* misuse of parmBytes (normally used for functions)
3521 * to save estimated stack position of this argument.
3522 * Normally this should be zero for RECEIVE iCodes.
3523 * No idea if this causes side effects on other ports. - dw
3525 ic->parmBytes = paramByteCounter;
3527 /* what stack position do we have? */
3528 paramByteCounter += getSize (sym->type);
3537 /*-----------------------------------------------------------------*/
3538 /* geniCodeFunctionBody - create the function body */
3539 /*-----------------------------------------------------------------*/
3541 geniCodeFunctionBody (ast * tree,int lvl)
3548 /* reset the auto generation */
3554 func = ast2iCode (tree->left,lvl+1);
3555 fetype = getSpec (operandType (func));
3557 savelineno = lineno;
3558 lineno = OP_SYMBOL (func)->lineDef;
3559 /* create an entry label */
3560 geniCodeLabel (entryLabel);
3561 lineno = savelineno;
3563 /* create a proc icode */
3564 ic = newiCode (FUNCTION, func, NULL);
3565 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3570 /* for all parameters that are passed
3571 on registers add a "receive" */
3572 geniCodeReceive (tree->values.args, func);
3574 /* generate code for the body */
3575 ast2iCode (tree->right,lvl+1);
3577 /* create a label for return */
3578 geniCodeLabel (returnLabel);
3580 /* now generate the end proc */
3581 ic = newiCode (ENDFUNCTION, func, NULL);
3587 /*-----------------------------------------------------------------*/
3588 /* geniCodeReturn - gen icode for 'return' statement */
3589 /*-----------------------------------------------------------------*/
3591 geniCodeReturn (operand * op)
3595 /* if the operand is present force an rvalue */
3597 op = geniCodeRValue (op, FALSE);
3599 ic = newiCode (RETURN, op, NULL);
3603 /*-----------------------------------------------------------------*/
3604 /* geniCodeIfx - generates code for extended if statement */
3605 /*-----------------------------------------------------------------*/
3607 geniCodeIfx (ast * tree,int lvl)
3610 operand *condition = ast2iCode (tree->left,lvl+1);
3613 /* if condition is null then exit */
3617 condition = geniCodeRValue (condition, FALSE);
3619 cetype = getSpec (operandType (condition));
3620 /* if the condition is a literal */
3621 if (IS_LITERAL (cetype))
3623 if (floatFromVal (condition->operand.valOperand))
3625 if (tree->trueLabel)
3626 geniCodeGoto (tree->trueLabel);
3632 if (tree->falseLabel)
3633 geniCodeGoto (tree->falseLabel);
3638 if (tree->trueLabel)
3640 ic = newiCodeCondition (condition,
3645 if (tree->falseLabel)
3646 geniCodeGoto (tree->falseLabel);
3650 ic = newiCodeCondition (condition,
3657 ast2iCode (tree->right,lvl+1);
3660 /*-----------------------------------------------------------------*/
3661 /* geniCodeJumpTable - tries to create a jump table for switch */
3662 /*-----------------------------------------------------------------*/
3664 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3666 int min, max, cnt = 1;
3673 int needRangeCheck = !optimize.noJTabBoundary
3674 || tree->values.switchVals.swDefault;
3675 sym_link *cetype = getSpec (operandType (cond));
3676 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3677 int sizeofMatchJump, sizeofJumpTable;
3680 if (!tree || !caseVals)
3683 /* the criteria for creating a jump table is */
3684 /* all integer numbers between the maximum & minimum must */
3685 /* be present , the maximum value should not exceed 255 */
3686 /* If not all integer numbers are present the algorithm */
3687 /* inserts jumps to the default label for the missing numbers */
3688 /* and decides later whether it is worth it */
3689 min = (int) floatFromVal (vch = caseVals);
3696 max = (int) floatFromVal (vch);
3698 /* Exit if the range is too large to handle with a jump table. */
3699 if (1 + max - min > port->jumptableCost.maxCount)
3702 switch (getSize (operandType (cond)))
3704 case 1: sizeIndex = 0; break;
3705 case 2: sizeIndex = 1; break;
3706 case 4: sizeIndex = 2; break;
3710 /* Compute the size cost of the range check and subtraction. */
3712 sizeofZeroMinCost = 0;
3716 if (!(min==0 && IS_UNSIGNED (cetype)))
3717 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3718 if (!IS_UNSIGNED (cetype))
3719 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3720 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3723 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3725 /* If the size cost of handling a non-zero minimum exceeds the */
3726 /* cost of extending the range down to zero, then it might be */
3727 /* better to extend the range to zero. */
3728 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3729 >= (min * port->jumptableCost.sizeofElement))
3731 /* Only extend the jump table if it would still be manageable. */
3732 if (1 + max <= port->jumptableCost.maxCount)
3735 if (IS_UNSIGNED (cetype))
3738 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3742 /* Compute the total size cost of a jump table. */
3743 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3744 + port->jumptableCost.sizeofDispatch
3745 + sizeofMinCost + sizeofMaxCost;
3747 /* Compute the total size cost of a match & jump sequence */
3748 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3750 /* If the size cost of the jump table is uneconomical then exit */
3751 if (sizeofMatchJump < sizeofJumpTable)
3754 /* The jump table is preferable. */
3756 /* First, a label for the default or missing cases. */
3757 if (tree->values.switchVals.swDefault)
3759 SNPRINTF (buffer, sizeof(buffer),
3761 tree->values.switchVals.swNum);
3765 SNPRINTF (buffer, sizeof(buffer),
3767 tree->values.switchVals.swNum);
3769 falseLabel = newiTempLabel (buffer);
3771 /* Build the list of labels for the jump table. */
3773 t = (int) floatFromVal (vch);
3774 for (i=min; i<=max; i++)
3778 /* Explicit case: make a new label for it. */
3779 SNPRINTF (buffer, sizeof(buffer),
3781 tree->values.switchVals.swNum,
3783 addSet (&labels, newiTempLabel (buffer));
3786 t = (int) floatFromVal (vch);
3790 /* Implicit case: use the default label. */
3791 addSet (&labels, falseLabel);
3795 /* first we rule out the boundary conditions */
3796 /* if only optimization says so */
3799 sym_link *cetype = getSpec (operandType (cond));
3800 /* no need to check the lower bound if
3801 the condition is unsigned & minimum value is zero */
3802 if (!(min == 0 && IS_UNSIGNED (cetype)))
3804 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3805 ic = newiCodeCondition (boundary, falseLabel, NULL);
3809 /* now for upper bounds */
3810 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3811 ic = newiCodeCondition (boundary, falseLabel, NULL);
3815 /* if the min is not zero then we no make it zero */
3818 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3819 if (!IS_LITERAL(getSpec(operandType(cond))))
3820 setOperandType (cond, UCHARTYPE);
3823 /* now create the jumptable */
3824 ic = newiCode (JUMPTABLE, NULL, NULL);
3825 IC_JTCOND (ic) = cond;
3826 IC_JTLABELS (ic) = labels;
3831 /*-----------------------------------------------------------------*/
3832 /* geniCodeSwitch - changes a switch to a if statement */
3833 /*-----------------------------------------------------------------*/
3835 geniCodeSwitch (ast * tree,int lvl)
3838 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3839 value *caseVals = tree->values.switchVals.swVals;
3840 symbol *trueLabel, *falseLabel;
3842 /* If the condition is a literal, then just jump to the */
3843 /* appropriate case label. */
3844 if (IS_LITERAL(getSpec(operandType(cond))))
3846 int switchVal, caseVal;
3848 switchVal = (int) floatFromVal (cond->operand.valOperand);
3851 caseVal = (int) floatFromVal (caseVals);
3852 if (caseVal == switchVal)
3854 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3855 tree->values.switchVals.swNum, caseVal);
3856 trueLabel = newiTempLabel (buffer);
3857 geniCodeGoto (trueLabel);
3860 caseVals = caseVals->next;
3862 goto defaultOrBreak;
3865 /* If cond is volatile, it might change while we are trying to */
3866 /* find the matching case. To avoid this possibility, make a */
3867 /* non-volatile copy to use instead. */
3868 if (IS_OP_VOLATILE (cond))
3873 newcond = newiTempOperand (operandType (cond), TRUE);
3874 newcond->isvolatile = 0;
3875 ic = newiCode ('=', NULL, cond);
3876 IC_RESULT (ic) = newcond;
3881 /* if we can make this a jump table */
3882 if (geniCodeJumpTable (cond, caseVals, tree))
3883 goto jumpTable; /* no need for the comparison */
3885 /* for the cases defined do */
3889 operand *compare = geniCodeLogic (cond,
3890 operandFromValue (caseVals),
3893 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3894 tree->values.switchVals.swNum,
3895 (int) floatFromVal (caseVals));
3896 trueLabel = newiTempLabel (buffer);
3898 ic = newiCodeCondition (compare, trueLabel, NULL);
3900 caseVals = caseVals->next;
3905 /* if default is present then goto break else break */
3906 if (tree->values.switchVals.swDefault)
3908 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3912 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3915 falseLabel = newiTempLabel (buffer);
3916 geniCodeGoto (falseLabel);
3919 ast2iCode (tree->right,lvl+1);
3922 /*-----------------------------------------------------------------*/
3923 /* geniCodeInline - intermediate code for inline assembler */
3924 /*-----------------------------------------------------------------*/
3926 geniCodeInline (ast * tree)
3930 ic = newiCode (INLINEASM, NULL, NULL);
3931 IC_INLINE (ic) = tree->values.inlineasm;
3935 /*-----------------------------------------------------------------*/
3936 /* geniCodeArrayInit - intermediate code for array initializer */
3937 /*-----------------------------------------------------------------*/
3939 geniCodeArrayInit (ast * tree, operand *array)
3943 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3944 ic = newiCode (ARRAYINIT, array, NULL);
3945 IC_ARRAYILIST (ic) = tree->values.constlist;
3947 operand *left=newOperand(), *right=newOperand();
3948 left->type=right->type=SYMBOL;
3949 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3950 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3951 ic = newiCode (ARRAYINIT, left, right);
3956 /*-----------------------------------------------------------------*/
3957 /* geniCodeCritical - intermediate code for a critical statement */
3958 /*-----------------------------------------------------------------*/
3960 geniCodeCritical (ast *tree, int lvl)
3966 if (!options.stackAuto)
3968 type = newLink(SPECIFIER);
3969 SPEC_VOLATILE(type) = 1;
3970 SPEC_NOUN(type) = V_BIT;
3971 SPEC_SCLS(type) = S_BIT;
3972 SPEC_BLEN(type) = 1;
3973 SPEC_BSTR(type) = 0;
3974 op = newiTempOperand(type, 1);
3977 /* If op is NULL, the original interrupt state will saved on */
3978 /* the stack. Otherwise, it will be saved in op. */
3980 /* Generate a save of the current interrupt state & disable */
3981 ic = newiCode (CRITICAL, NULL, NULL);
3982 IC_RESULT (ic) = op;
3985 /* Generate the critical code sequence */
3986 if (tree->left && tree->left->type == EX_VALUE)
3987 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3989 ast2iCode (tree->left,lvl+1);
3991 /* Generate a restore of the original interrupt state */
3992 ic = newiCode (ENDCRITICAL, NULL, op);
3996 /*-----------------------------------------------------------------*/
3997 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3998 /* particular case. Ie : assigning or dereferencing array or ptr */
3999 /*-----------------------------------------------------------------*/
4000 set * lvaluereqSet = NULL;
4001 typedef struct lvalItem
4008 /*-----------------------------------------------------------------*/
4009 /* addLvaluereq - add a flag for lvalreq for current ast level */
4010 /*-----------------------------------------------------------------*/
4011 void addLvaluereq(int lvl)
4013 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4016 addSetHead(&lvaluereqSet,lpItem);
4019 /*-----------------------------------------------------------------*/
4020 /* delLvaluereq - del a flag for lvalreq for current ast level */
4021 /*-----------------------------------------------------------------*/
4025 lpItem = getSet(&lvaluereqSet);
4026 if(lpItem) Safe_free(lpItem);
4028 /*-----------------------------------------------------------------*/
4029 /* clearLvaluereq - clear lvalreq flag */
4030 /*-----------------------------------------------------------------*/
4031 void clearLvaluereq()
4034 lpItem = peekSet(lvaluereqSet);
4035 if(lpItem) lpItem->req = 0;
4037 /*-----------------------------------------------------------------*/
4038 /* getLvaluereq - get the last lvalreq level */
4039 /*-----------------------------------------------------------------*/
4040 int getLvaluereqLvl()
4043 lpItem = peekSet(lvaluereqSet);
4044 if(lpItem) return lpItem->lvl;
4047 /*-----------------------------------------------------------------*/
4048 /* isLvaluereq - is lvalreq valid for this level ? */
4049 /*-----------------------------------------------------------------*/
4050 int isLvaluereq(int lvl)
4053 lpItem = peekSet(lvaluereqSet);
4054 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4058 /*-----------------------------------------------------------------*/
4059 /* ast2iCode - creates an icodeList from an ast */
4060 /*-----------------------------------------------------------------*/
4062 ast2iCode (ast * tree,int lvl)
4064 operand *left = NULL;
4065 operand *right = NULL;
4069 /* set the global variables for filename & line number */
4071 filename = tree->filename;
4073 lineno = tree->lineno;
4075 block = tree->block;
4077 scopeLevel = tree->level;
4079 seqPoint = tree->seqPoint;
4081 if (tree->type == EX_VALUE)
4082 return operandFromValue (tree->opval.val);
4084 if (tree->type == EX_LINK)
4085 return operandFromLink (tree->opval.lnk);
4087 /* if we find a nullop */
4088 if (tree->type == EX_OP &&
4089 (tree->opval.op == NULLOP ||
4090 tree->opval.op == BLOCK))
4092 if (tree->left && tree->left->type == EX_VALUE)
4093 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4095 ast2iCode (tree->left,lvl+1);
4096 if (tree->right && tree->right->type == EX_VALUE)
4097 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4099 ast2iCode (tree->right,lvl+1);
4103 /* special cases for not evaluating */
4104 if (tree->opval.op != ':' &&
4105 tree->opval.op != '?' &&
4106 tree->opval.op != CALL &&
4107 tree->opval.op != IFX &&
4108 tree->opval.op != AND_OP &&
4109 tree->opval.op != OR_OP &&
4110 tree->opval.op != LABEL &&
4111 tree->opval.op != GOTO &&
4112 tree->opval.op != SWITCH &&
4113 tree->opval.op != FUNCTION &&
4114 tree->opval.op != INLINEASM &&
4115 tree->opval.op != CRITICAL)
4118 if (IS_ASSIGN_OP (tree->opval.op) ||
4119 IS_DEREF_OP (tree) ||
4120 (tree->opval.op == '&' && !tree->right) ||
4121 tree->opval.op == PTR_OP)
4124 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4125 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4128 left = operandFromAst (tree->left,lvl);
4130 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4131 left = geniCodeRValue (left, TRUE);
4135 left = operandFromAst (tree->left,lvl);
4137 if (tree->opval.op == INC_OP ||
4138 tree->opval.op == DEC_OP)
4141 right = operandFromAst (tree->right,lvl);
4146 right = operandFromAst (tree->right,lvl);
4150 /* now depending on the type of operand */
4151 /* this will be a biggy */
4152 switch (tree->opval.op)
4155 case '[': /* array operation */
4157 //sym_link *ltype = operandType (left);
4158 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4159 left = geniCodeRValue (left, FALSE);
4160 right = geniCodeRValue (right, TRUE);
4163 return geniCodeArray (left, right,lvl);
4165 case '.': /* structure dereference */
4166 if (IS_PTR (operandType (left)))
4167 left = geniCodeRValue (left, TRUE);
4169 left = geniCodeRValue (left, FALSE);
4171 return geniCodeStruct (left, right, tree->lvalue);
4173 case PTR_OP: /* structure pointer dereference */
4176 pType = operandType (left);
4177 left = geniCodeRValue (left, TRUE);
4179 setOClass (pType, getSpec (operandType (left)));
4182 return geniCodeStruct (left, right, tree->lvalue);
4184 case INC_OP: /* increment operator */
4186 return geniCodePostInc (left);
4188 return geniCodePreInc (right, tree->lvalue);
4190 case DEC_OP: /* decrement operator */
4192 return geniCodePostDec (left);
4194 return geniCodePreDec (right, tree->lvalue);
4196 case '&': /* bitwise and or address of operator */
4198 { /* this is a bitwise operator */
4199 left = geniCodeRValue (left, FALSE);
4200 right = geniCodeRValue (right, FALSE);
4201 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4204 return geniCodeAddressOf (left);
4206 case '|': /* bitwise or & xor */
4208 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4209 geniCodeRValue (right, FALSE),
4214 return geniCodeDivision (geniCodeRValue (left, FALSE),
4215 geniCodeRValue (right, FALSE),
4216 getResultTypeFromType (tree->ftype));
4219 return geniCodeModulus (geniCodeRValue (left, FALSE),
4220 geniCodeRValue (right, FALSE),
4221 getResultTypeFromType (tree->ftype));
4224 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4225 geniCodeRValue (right, FALSE),
4226 getResultTypeFromType (tree->ftype));
4228 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4232 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4233 geniCodeRValue (right, FALSE),
4234 getResultTypeFromType (tree->ftype));
4236 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4240 return geniCodeAdd (geniCodeRValue (left, FALSE),
4241 geniCodeRValue (right, FALSE),
4242 getResultTypeFromType (tree->ftype),
4245 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4248 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4249 geniCodeRValue (right, FALSE),
4250 getResultTypeFromType (tree->ftype));
4253 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4254 geniCodeRValue (right, FALSE));
4256 #if 0 // this indeed needs a second thought
4260 // let's keep this simple: get the rvalue we need
4261 op=geniCodeRValue (right, FALSE);
4262 // now cast it to whatever we want
4263 op=geniCodeCast (operandType(left), op, FALSE);
4264 // if this is going to be used as an lvalue, make it so
4270 #else // bug #604575, is it a bug ????
4271 return geniCodeCast (operandType (left),
4272 geniCodeRValue (right, FALSE), FALSE);
4279 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4284 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4285 setOperandType (op, UCHARTYPE);
4292 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4293 geniCodeRValue (right, FALSE),
4295 setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4300 return geniCodeLogicAndOr (tree, lvl);
4307 /* different compilers (even different gccs) evaluate
4308 the two calls in a different order. to get the same
4309 result on all machines we've to specify a clear sequence.
4310 return geniCodeLogic (geniCodeRValue (left, FALSE),
4311 geniCodeRValue (right, FALSE),
4315 operand *leftOp, *rightOp;
4317 leftOp = geniCodeRValue (left , FALSE);
4318 rightOp = geniCodeRValue (right, FALSE);
4320 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4323 return geniCodeConditional (tree,lvl);
4326 return operandFromLit (getSize (tree->right->ftype));
4330 sym_link *rtype = operandType (right);
4331 sym_link *ltype = operandType (left);
4332 if (IS_PTR (rtype) && IS_ITEMP (right)
4333 && right->isaddr && compareType (rtype->next, ltype) == 1)
4334 right = geniCodeRValue (right, TRUE);
4336 right = geniCodeRValue (right, FALSE);
4338 geniCodeAssign (left, right, 0, 1);
4343 geniCodeAssign (left,
4344 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4346 geniCodeRValue (right, FALSE),
4347 getResultTypeFromType (tree->ftype)),
4352 geniCodeAssign (left,
4353 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4355 geniCodeRValue (right, FALSE),
4356 getResultTypeFromType (tree->ftype)),
4360 geniCodeAssign (left,
4361 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4363 geniCodeRValue (right, FALSE),
4364 getResultTypeFromType (tree->ftype)),
4368 sym_link *rtype = operandType (right);
4369 sym_link *ltype = operandType (left);
4370 if (IS_PTR (rtype) && IS_ITEMP (right)
4371 && right->isaddr && compareType (rtype->next, ltype) == 1)
4372 right = geniCodeRValue (right, TRUE);
4374 right = geniCodeRValue (right, FALSE);
4377 return geniCodeAssign (left,
4378 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4381 getResultTypeFromType (tree->ftype),
4387 sym_link *rtype = operandType (right);
4388 sym_link *ltype = operandType (left);
4389 if (IS_PTR (rtype) && IS_ITEMP (right)
4390 && right->isaddr && compareType (rtype->next, ltype) == 1)
4392 right = geniCodeRValue (right, TRUE);
4396 right = geniCodeRValue (right, FALSE);
4399 geniCodeAssign (left,
4400 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4403 getResultTypeFromType (tree->ftype)),
4408 geniCodeAssign (left,
4409 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4411 geniCodeRValue (right, FALSE),
4412 getResultTypeFromType (tree->ftype)),
4416 geniCodeAssign (left,
4417 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4419 geniCodeRValue (right, FALSE)), 0, 1);
4422 geniCodeAssign (left,
4423 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4425 geniCodeRValue (right, FALSE),
4427 operandType (left)), 0, 1);
4430 geniCodeAssign (left,
4431 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4433 geniCodeRValue (right, FALSE),
4435 operandType (left)), 0, 1);
4438 geniCodeAssign (left,
4439 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4441 geniCodeRValue (right, FALSE),
4443 operandType (left)), 0, 1);
4445 return geniCodeRValue (right, FALSE);
4448 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4451 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4452 return ast2iCode (tree->right,lvl+1);
4455 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4456 return ast2iCode (tree->right,lvl+1);
4459 geniCodeFunctionBody (tree,lvl);
4463 geniCodeReturn (right);
4467 geniCodeIfx (tree,lvl);
4471 geniCodeSwitch (tree,lvl);
4475 geniCodeInline (tree);
4479 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4483 geniCodeCritical (tree, lvl);
4489 /*-----------------------------------------------------------------*/
4490 /* reverseICChain - gets from the list and creates a linkedlist */
4491 /*-----------------------------------------------------------------*/
4498 while ((loop = getSet (&iCodeChain)))
4510 /*-----------------------------------------------------------------*/
4511 /* iCodeFromAst - given an ast will convert it to iCode */
4512 /*-----------------------------------------------------------------*/
4514 iCodeFromAst (ast * tree)
4516 returnLabel = newiTempLabel ("_return");
4517 entryLabel = newiTempLabel ("_entry");
4519 return reverseiCChain ();
4522 static const char *opTypeToStr(OPTYPE op)
4526 case SYMBOL: return "symbol";
4527 case VALUE: return "value";
4528 case TYPE: return "type";
4530 return "undefined type";
4534 operand *validateOpType(operand *op,
4541 if (op && op->type == type)
4546 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4547 " expected %s, got %s\n",
4548 macro, args, file, line,
4549 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4551 return op; // never reached, makes compiler happy.