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,
2415 (getArraySizePtr(left) >= INTSIZE) ?
2418 /* Even if right is a 'unsigned char',
2419 the result will be a 'signed int' due to the promotion rules.
2420 It doesn't make sense when accessing arrays, so let's fix it here: */
2422 SPEC_USIGN (getSpec (operandType (right))) = 1;
2424 resType = copyLinkChain (ltype);
2427 { // make them the same size
2428 resType = usualBinaryConversions (&left, &right, resultType, '+');
2431 /* if they are both literals then we know */
2432 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2433 && left->isLiteral && right->isLiteral)
2434 return operandFromValue (valPlus (valFromType (ltype),
2435 valFromType (rtype)));
2437 ic = newiCode ('+', left, right);
2439 IC_RESULT (ic) = newiTempOperand (resType, 1);
2440 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2442 /* if left or right is a float then support
2444 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2445 || IS_FIXED (ltype) || IS_FIXED (rtype))
2450 return IC_RESULT (ic);
2454 /*-----------------------------------------------------------------*/
2455 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2456 /*-----------------------------------------------------------------*/
2458 aggrToPtr (sym_link * type, bool force)
2463 if (IS_PTR (type) && !force)
2466 etype = getSpec (type);
2467 ptype = newLink (DECLARATOR);
2471 /* set the pointer depending on the storage class */
2472 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2476 /*------------------------------------------------------------------*/
2477 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2478 /*------------------------------------------------------------------*/
2480 aggrToPtrDclType (sym_link * type, bool force)
2482 if (IS_PTR (type) && !force)
2483 return DCL_TYPE (type);
2485 /* return the pointer depending on the storage class */
2486 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2489 /*-----------------------------------------------------------------*/
2490 /* geniCodeArray2Ptr - array to pointer */
2491 /*-----------------------------------------------------------------*/
2493 geniCodeArray2Ptr (operand * op)
2495 sym_link *optype = operandType (op);
2496 sym_link *opetype = getSpec (optype);
2498 /* set the pointer depending on the storage class */
2499 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2506 /*-----------------------------------------------------------------*/
2507 /* geniCodeArray - array access */
2508 /*-----------------------------------------------------------------*/
2510 geniCodeArray (operand * left, operand * right, int lvl)
2514 sym_link *ltype = operandType (left);
2519 if (IS_PTR (ltype->next) && left->isaddr)
2521 left = geniCodeRValue (left, FALSE);
2524 return geniCodeDerefPtr (geniCodeAdd (left,
2526 (getArraySizePtr(left) >= INTSIZE) ?
2532 size = operandFromLit (getSize (ltype->next));
2533 SPEC_USIGN (getSpec (operandType (size))) = 1;
2534 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2535 right = geniCodeMultiply (right,
2537 (getArraySizePtr(left) >= INTSIZE) ?
2540 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2541 It doesn't make sense when accessing arrays, so let's fix it here: */
2543 SPEC_USIGN (getSpec (operandType (right))) = 1;
2544 /* we can check for limits here */
2545 /* already done in SDCCast.c
2546 if (isOperandLiteral (right) &&
2549 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2551 werror (W_IDX_OUT_OF_BOUNDS,
2552 (int) operandLitValue (right) / getSize (ltype->next),
2557 ic = newiCode ('+', left, right);
2559 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2560 !IS_AGGREGATE (ltype->next) &&
2561 !IS_PTR (ltype->next))
2562 ? ltype : ltype->next), 0);
2564 if (!IS_AGGREGATE (ltype->next))
2566 IC_RESULT (ic)->isaddr = 1;
2567 IC_RESULT (ic)->aggr2ptr = 1;
2571 return IC_RESULT (ic);
2574 /*-----------------------------------------------------------------*/
2575 /* geniCodeStruct - generates intermediate code for structures */
2576 /*-----------------------------------------------------------------*/
2578 geniCodeStruct (operand * left, operand * right, bool islval)
2581 sym_link *type = operandType (left);
2582 sym_link *etype = getSpec (type);
2584 symbol *element = getStructElement (SPEC_STRUCT (etype),
2585 right->operand.symOperand);
2587 wassert(IS_SYMOP(right));
2589 /* add the offset */
2590 ic = newiCode ('+', left, operandFromLit (element->offset));
2592 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2594 /* preserve the storage & output class of the struct */
2595 /* as well as the volatile attribute */
2596 retype = getSpec (operandType (IC_RESULT (ic)));
2597 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2598 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2599 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2600 SPEC_CONST (retype) |= SPEC_CONST (etype);
2602 if (IS_PTR (element->type))
2603 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2605 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2608 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2611 /*-----------------------------------------------------------------*/
2612 /* geniCodePostInc - generate int code for Post increment */
2613 /*-----------------------------------------------------------------*/
2615 geniCodePostInc (operand * op)
2619 sym_link *optype = operandType (op);
2621 operand *rv = (IS_ITEMP (op) ?
2622 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2624 sym_link *rvtype = operandType (rv);
2627 /* if this is not an address we have trouble */
2630 werror (E_LVALUE_REQUIRED, "++");
2634 rOp = newiTempOperand (rvtype, 0);
2635 OP_SYMBOL(rOp)->noSpilLoc = 1;
2638 OP_SYMBOL(rv)->noSpilLoc = 1;
2640 geniCodeAssign (rOp, rv, 0, 0);
2642 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2644 werror(W_SIZEOF_VOID);
2645 if (IS_FLOAT (rvtype))
2646 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2647 else if (IS_FIXED16X16 (rvtype))
2648 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2650 ic = newiCode ('+', rv, operandFromLit (size));
2652 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2655 geniCodeAssign (op, result, 0, 0);
2661 /*-----------------------------------------------------------------*/
2662 /* geniCodePreInc - generate code for preIncrement */
2663 /*-----------------------------------------------------------------*/
2665 geniCodePreInc (operand * op, bool lvalue)
2668 sym_link *optype = operandType (op);
2669 operand *rop = (IS_ITEMP (op) ?
2670 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2672 sym_link *roptype = operandType (rop);
2678 werror (E_LVALUE_REQUIRED, "++");
2682 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2684 werror(W_SIZEOF_VOID);
2685 if (IS_FLOAT (roptype))
2686 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2687 else if (IS_FIXED16X16 (roptype))
2688 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2690 ic = newiCode ('+', rop, operandFromLit (size));
2691 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2694 (void) geniCodeAssign (op, result, 0, 0);
2695 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2701 /*-----------------------------------------------------------------*/
2702 /* geniCodePostDec - generates code for Post decrement */
2703 /*-----------------------------------------------------------------*/
2705 geniCodePostDec (operand * op)
2709 sym_link *optype = operandType (op);
2711 operand *rv = (IS_ITEMP (op) ?
2712 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2714 sym_link *rvtype = operandType (rv);
2717 /* if this is not an address we have trouble */
2720 werror (E_LVALUE_REQUIRED, "--");
2724 rOp = newiTempOperand (rvtype, 0);
2725 OP_SYMBOL(rOp)->noSpilLoc = 1;
2728 OP_SYMBOL(rv)->noSpilLoc = 1;
2730 geniCodeAssign (rOp, rv, 0, 0);
2732 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2734 werror(W_SIZEOF_VOID);
2735 if (IS_FLOAT (rvtype))
2736 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2737 else if (IS_FIXED16X16 (rvtype))
2738 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2740 ic = newiCode ('-', rv, operandFromLit (size));
2742 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2745 geniCodeAssign (op, result, 0, 0);
2751 /*-----------------------------------------------------------------*/
2752 /* geniCodePreDec - generate code for pre decrement */
2753 /*-----------------------------------------------------------------*/
2755 geniCodePreDec (operand * op, bool lvalue)
2758 sym_link *optype = operandType (op);
2759 operand *rop = (IS_ITEMP (op) ?
2760 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2762 sym_link *roptype = operandType (rop);
2768 werror (E_LVALUE_REQUIRED, "--");
2772 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2774 werror(W_SIZEOF_VOID);
2775 if (IS_FLOAT (roptype))
2776 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2777 else if (IS_FIXED16X16 (roptype))
2778 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2780 ic = newiCode ('-', rop, operandFromLit (size));
2781 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2784 (void) geniCodeAssign (op, result, 0, 0);
2785 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2792 /*-----------------------------------------------------------------*/
2793 /* geniCodeBitwise - gen int code for bitWise operators */
2794 /*-----------------------------------------------------------------*/
2796 geniCodeBitwise (operand * left, operand * right,
2797 int oper, sym_link * resType)
2801 left = geniCodeCast (resType, left, TRUE);
2802 right = geniCodeCast (resType, right, TRUE);
2804 ic = newiCode (oper, left, right);
2805 IC_RESULT (ic) = newiTempOperand (resType, 0);
2808 return IC_RESULT (ic);
2811 /*-----------------------------------------------------------------*/
2812 /* geniCodeAddressOf - gens icode for '&' address of operator */
2813 /*-----------------------------------------------------------------*/
2815 geniCodeAddressOf (operand * op)
2819 sym_link *optype = operandType (op);
2820 sym_link *opetype = getSpec (optype);
2822 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2824 op = operandFromOperand (op);
2829 /* lvalue check already done in decorateType */
2830 /* this must be a lvalue */
2831 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2832 /* werror (E_LVALUE_REQUIRED,"&"); */
2836 p = newLink (DECLARATOR);
2838 /* set the pointer depending on the storage class */
2839 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2841 p->next = copyLinkChain (optype);
2843 /* if already a temp */
2846 setOperandType (op, p);
2851 /* other wise make this of the type coming in */
2852 ic = newiCode (ADDRESS_OF, op, NULL);
2853 IC_RESULT (ic) = newiTempOperand (p, 1);
2854 IC_RESULT (ic)->isaddr = 0;
2856 return IC_RESULT (ic);
2859 /*-----------------------------------------------------------------*/
2860 /* setOClass - sets the output class depending on the pointer type */
2861 /*-----------------------------------------------------------------*/
2863 setOClass (sym_link * ptr, sym_link * spec)
2865 switch (DCL_TYPE (ptr))
2868 SPEC_OCLS (spec) = data;
2872 SPEC_OCLS (spec) = generic;
2876 SPEC_OCLS (spec) = xdata;
2880 SPEC_OCLS (spec) = code;
2884 SPEC_OCLS (spec) = idata;
2888 SPEC_OCLS (spec) = xstack;
2892 SPEC_OCLS (spec) = eeprom;
2901 /*-----------------------------------------------------------------*/
2902 /* geniCodeDerefPtr - dereference pointer with '*' */
2903 /*-----------------------------------------------------------------*/
2905 geniCodeDerefPtr (operand * op,int lvl)
2907 sym_link *rtype, *retype;
2908 sym_link *optype = operandType (op);
2910 // if this is an array then array access
2911 if (IS_ARRAY (optype)) {
2912 // don't worry, this will be optimized out later
2913 return geniCodeArray (op, operandFromLit (0), lvl);
2916 // just in case someone screws up
2917 wassert (IS_PTR (optype));
2919 if (IS_TRUE_SYMOP (op))
2922 op = geniCodeRValue (op, TRUE);
2925 /* now get rid of the pointer part */
2926 if (isLvaluereq(lvl) && IS_ITEMP (op))
2928 retype = getSpec (rtype = copyLinkChain (optype));
2932 retype = getSpec (rtype = copyLinkChain (optype->next));
2933 /* outputclass needs 2b updated */
2934 setOClass (optype, retype);
2937 op->isGptr = IS_GENPTR (optype);
2939 op->isaddr = (IS_PTR (rtype) ||
2940 IS_STRUCT (rtype) ||
2946 if (!isLvaluereq(lvl))
2947 op = geniCodeRValue (op, TRUE);
2949 setOperandType (op, rtype);
2954 /*-----------------------------------------------------------------*/
2955 /* geniCodeUnaryMinus - does a unary minus of the operand */
2956 /*-----------------------------------------------------------------*/
2958 geniCodeUnaryMinus (operand * op)
2961 sym_link *optype = operandType (op);
2963 if (IS_LITERAL (optype))
2964 return operandFromLit (-floatFromVal (op->operand.valOperand));
2966 ic = newiCode (UNARYMINUS, op, NULL);
2967 IC_RESULT (ic) = newiTempOperand (optype, 0);
2969 return IC_RESULT (ic);
2972 /*-----------------------------------------------------------------*/
2973 /* geniCodeLeftShift - gen i code for left shift */
2974 /*-----------------------------------------------------------------*/
2976 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2981 ic = newiCode (LEFT_OP, left, right);
2983 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2984 IC_RESULT (ic) = newiTempOperand (resType, 0);
2986 return IC_RESULT (ic);
2989 /*-----------------------------------------------------------------*/
2990 /* geniCodeRightShift - gen i code for right shift */
2991 /*-----------------------------------------------------------------*/
2993 geniCodeRightShift (operand * left, operand * right)
2997 ic = newiCode (RIGHT_OP, left, right);
2998 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3000 return IC_RESULT (ic);
3003 /*-----------------------------------------------------------------*/
3004 /* geniCodeLogic- logic code */
3005 /*-----------------------------------------------------------------*/
3007 geniCodeLogic (operand * left, operand * right, int op)
3011 sym_link *rtype = operandType (right);
3012 sym_link *ltype = operandType (left);
3014 /* left is integral type and right is literal then
3015 check if the literal value is within bounds */
3016 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3018 checkConstantRange(ltype,
3019 OP_VALUE(right), "compare operation", 1);
3022 /* if one operand is a pointer and the other is a literal generic void pointer,
3023 change the type of the literal generic void pointer to match the other pointer */
3024 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3025 && IS_PTR (rtype) && !IS_GENPTR(rtype))
3027 /* find left's definition */
3028 ic = (iCode *) setFirstItem (iCodeChain);
3031 if (((ic->op == CAST) || (ic->op == '='))
3032 && isOperandEqual(left, IC_RESULT (ic)))
3035 ic = setNextItem (iCodeChain);
3037 /* if casting literal to generic pointer, then cast to rtype instead */
3038 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3040 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3041 ltype = operandType(left);
3044 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3045 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3047 /* find right's definition */
3048 ic = (iCode *) setFirstItem (iCodeChain);
3051 if (((ic->op == CAST) || (ic->op == '='))
3052 && isOperandEqual(right, IC_RESULT (ic)))
3055 ic = setNextItem (iCodeChain);
3057 /* if casting literal to generic pointer, then cast to rtype instead */
3058 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3060 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3061 rtype = operandType(right);
3065 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3067 ic = newiCode (op, left, right);
3068 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3070 /* if comparing float
3071 and not a '==' || '!=' || '&&' || '||' (these
3073 if (IS_FLOAT(ctype) &&
3080 /* if comparing a fixed type use support functions */
3081 if (IS_FIXED(ctype))
3085 return IC_RESULT (ic);
3088 /*-----------------------------------------------------------------*/
3089 /* geniCodeLogicAndOr - && || operations */
3090 /*-----------------------------------------------------------------*/
3092 geniCodeLogicAndOr (ast *tree, int lvl)
3096 symbol *falseLabel = newiTempLabel (NULL);
3097 symbol *trueLabel = newiTempLabel (NULL);
3098 symbol *exitLabel = newiTempLabel (NULL);
3099 operand *op, *result, *condition;
3101 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3102 They can be reenabled by executing the following block. If you find
3103 a decent optimization you could start right here:
3108 operand *leftOp, *rightOp;
3110 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3111 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3113 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3117 /* generate two IFX for the '&&' or '||' op */
3119 /* evaluate left operand */
3120 condition = ast2iCode (tree->left, lvl + 1);
3121 op = geniCodeRValue (condition, FALSE);
3123 /* test left operand */
3124 if (tree->opval.op == AND_OP)
3125 ic = newiCodeCondition (op, NULL, falseLabel);
3127 ic = newiCodeCondition (op, trueLabel, NULL);
3130 /* evaluate right operand */
3131 condition = ast2iCode (tree->right, lvl + 1);
3132 op = geniCodeRValue (condition, FALSE);
3134 /* test right operand */
3135 ic = newiCodeCondition (op, trueLabel, NULL);
3138 /* store 0 or 1 in result */
3139 type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3140 result = newiTempOperand (type, 1);
3142 geniCodeLabel (falseLabel);
3143 geniCodeAssign (result, operandFromLit (0), 0, 0);
3144 /* generate an unconditional goto */
3145 geniCodeGoto (exitLabel);
3147 geniCodeLabel (trueLabel);
3148 geniCodeAssign (result, operandFromLit (1), 0, 0);
3150 geniCodeLabel (exitLabel);
3155 /*-----------------------------------------------------------------*/
3156 /* geniCodeUnary - for a generic unary operation */
3157 /*-----------------------------------------------------------------*/
3159 geniCodeUnary (operand * op, int oper)
3161 iCode *ic = newiCode (oper, op, NULL);
3163 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3165 return IC_RESULT (ic);
3168 /*-----------------------------------------------------------------*/
3169 /* geniCodeBinary - for a generic binary operation */
3170 /*-----------------------------------------------------------------*/
3172 geniCodeBinary (operand * left, operand * right, int oper)
3174 iCode *ic = newiCode (oper, left, right);
3176 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3178 return IC_RESULT (ic);
3181 /*-----------------------------------------------------------------*/
3182 /* geniCodeConditional - geniCode for '?' ':' operation */
3183 /*-----------------------------------------------------------------*/
3185 geniCodeConditional (ast * tree,int lvl)
3188 symbol *falseLabel = newiTempLabel (NULL);
3189 symbol *exitLabel = newiTempLabel (NULL);
3190 operand *cond = ast2iCode (tree->left,lvl+1);
3191 operand *true, *false, *result;
3193 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3197 true = ast2iCode (tree->right->left,lvl+1);
3199 /* move the value to a new Operand */
3200 result = newiTempOperand (tree->right->ftype, 0);
3201 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3203 /* generate an unconditional goto */
3204 geniCodeGoto (exitLabel);
3206 /* now for the right side */
3207 geniCodeLabel (falseLabel);
3209 false = ast2iCode (tree->right->right,lvl+1);
3210 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3212 /* create the exit label */
3213 geniCodeLabel (exitLabel);
3218 /*-----------------------------------------------------------------*/
3219 /* geniCodeAssign - generate code for assignment */
3220 /*-----------------------------------------------------------------*/
3222 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3225 sym_link *ltype = operandType (left);
3226 sym_link *rtype = operandType (right);
3228 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3230 werror (E_LVALUE_REQUIRED, "assignment");
3234 /* left is integral type and right is literal then
3235 check if the literal value is within bounds */
3236 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3238 checkConstantRange(ltype,
3239 OP_VALUE(right), "= operation", 0);
3242 /* if the left & right type don't exactly match */
3243 /* if pointer set then make sure the check is
3244 done with the type & not the pointer */
3245 /* then cast rights type to left */
3247 /* first check the type for pointer assignement */
3248 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3249 compareType (ltype, rtype) <= 0)
3251 if (compareType (ltype->next, rtype) < 0)
3252 right = geniCodeCast (ltype->next, right, TRUE);
3254 else if (compareType (ltype, rtype) < 0)
3255 right = geniCodeCast (ltype, right, TRUE);
3257 /* If left is a true symbol & ! volatile
3258 create an assignment to temporary for
3259 the right & then assign this temporary
3260 to the symbol. This is SSA (static single
3261 assignment). Isn't it simple and folks have
3262 published mountains of paper on it */
3263 if (IS_TRUE_SYMOP (left) &&
3264 !isOperandVolatile (left, FALSE) &&
3265 isOperandGlobal (left))
3270 if (IS_TRUE_SYMOP (right))
3271 sym = OP_SYMBOL (right);
3272 ic = newiCode ('=', NULL, right);
3273 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3274 /* avoid double fetch from volatile right, see bug 1369874 */
3275 if (!isOperandVolatile (right, FALSE))
3276 SPIL_LOC (newRight) = sym;
3281 ic = newiCode ('=', NULL, right);
3282 IC_RESULT (ic) = left;
3285 /* if left isgptr flag is set then support
3286 routine will be required */
3290 ic->nosupdate = nosupdate;
3294 /*-----------------------------------------------------------------*/
3295 /* geniCodeDummyRead - generate code for dummy read */
3296 /*-----------------------------------------------------------------*/
3298 geniCodeDummyRead (operand * op)
3301 sym_link *type = operandType (op);
3303 if (!IS_VOLATILE(type))
3306 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3312 /*-----------------------------------------------------------------*/
3313 /* geniCodeSEParms - generate code for side effecting fcalls */
3314 /*-----------------------------------------------------------------*/
3316 geniCodeSEParms (ast * parms,int lvl)
3321 if (parms->type == EX_OP && parms->opval.op == PARAM)
3323 geniCodeSEParms (parms->left,lvl);
3324 geniCodeSEParms (parms->right,lvl);
3328 /* hack don't like this but too lazy to think of
3330 if (IS_ADDRESS_OF_OP (parms))
3331 parms->left->lvalue = 1;
3333 if (IS_CAST_OP (parms) &&
3334 IS_PTR (parms->ftype) &&
3335 IS_ADDRESS_OF_OP (parms->right))
3336 parms->right->left->lvalue = 1;
3338 parms->opval.oprnd =
3339 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3341 parms->type = EX_OPERAND;
3342 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3343 SPEC_ARGREG(parms->ftype);
3346 /*-----------------------------------------------------------------*/
3347 /* geniCodeParms - generates parameters */
3348 /*-----------------------------------------------------------------*/
3350 geniCodeParms (ast * parms, value *argVals, int *stack,
3351 sym_link * ftype, int lvl)
3359 if (argVals==NULL) {
3361 argVals = FUNC_ARGS (ftype);
3364 /* if this is a param node then do the left & right */
3365 if (parms->type == EX_OP && parms->opval.op == PARAM)
3367 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3368 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3372 /* get the parameter value */
3373 if (parms->type == EX_OPERAND)
3374 pval = parms->opval.oprnd;
3377 /* maybe this else should go away ?? */
3378 /* hack don't like this but too lazy to think of
3380 if (IS_ADDRESS_OF_OP (parms))
3381 parms->left->lvalue = 1;
3383 if (IS_CAST_OP (parms) &&
3384 IS_PTR (parms->ftype) &&
3385 IS_ADDRESS_OF_OP (parms->right))
3386 parms->right->left->lvalue = 1;
3388 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3391 /* if register parm then make it a send */
3392 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3393 IFFUNC_ISBUILTIN(ftype))
3395 ic = newiCode (SEND, pval, NULL);
3396 ic->argreg = SPEC_ARGREG(parms->etype);
3397 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3402 /* now decide whether to push or assign */
3403 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3407 operand *top = operandFromSymbol (argVals->sym);
3408 /* clear useDef and other bitVectors */
3409 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3410 geniCodeAssign (top, pval, 1, 0);
3414 sym_link *p = operandType (pval);
3416 ic = newiCode (IPUSH, pval, NULL);
3418 /* update the stack adjustment */
3419 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3424 argVals=argVals->next;
3428 /*-----------------------------------------------------------------*/
3429 /* geniCodeCall - generates temp code for calling */
3430 /*-----------------------------------------------------------------*/
3432 geniCodeCall (operand * left, ast * parms,int lvl)
3436 sym_link *type, *etype;
3440 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3441 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3442 werror (E_FUNCTION_EXPECTED);
3443 return operandFromValue(valueFromLit(0));
3446 /* take care of parameters with side-effecting
3447 function calls in them, this is required to take care
3448 of overlaying function parameters */
3449 geniCodeSEParms (parms,lvl);
3451 ftype = operandType (left);
3452 if (IS_FUNCPTR (ftype))
3453 ftype = ftype->next;
3455 /* first the parameters */
3456 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3458 /* now call : if symbol then pcall */
3459 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3460 ic = newiCode (PCALL, left, NULL);
3462 ic = newiCode (CALL, left, NULL);
3465 type = copyLinkChain (ftype->next);
3466 etype = getSpec (type);
3467 SPEC_EXTR (etype) = 0;
3468 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3472 /* stack adjustment after call */
3473 ic->parmBytes = stack;
3478 /*-----------------------------------------------------------------*/
3479 /* geniCodeReceive - generate intermediate code for "receive" */
3480 /*-----------------------------------------------------------------*/
3482 geniCodeReceive (value * args, operand * func)
3484 unsigned char paramByteCounter = 0;
3486 /* for all arguments that are passed in registers */
3489 if (IS_REGPARM (args->etype))
3491 operand *opr = operandFromValue (args);
3493 symbol *sym = OP_SYMBOL (opr);
3496 /* we will use it after all optimizations
3497 and before liveRange calculation */
3498 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3501 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3502 options.stackAuto == 0 &&
3503 (!(options.model == MODEL_FLAT24)) )
3508 opl = newiTempOperand (args->type, 0);
3510 sym->reqv->key = sym->key;
3511 OP_SYMBOL (sym->reqv)->key = sym->key;
3512 OP_SYMBOL (sym->reqv)->isreqv = 1;
3513 OP_SYMBOL (sym->reqv)->islocal = 0;
3514 SPIL_LOC (sym->reqv) = sym;
3518 ic = newiCode (RECEIVE, func, NULL);
3519 ic->argreg = SPEC_ARGREG(args->etype);
3520 if (ic->argreg == 1) {
3521 currFunc->recvSize = getSize (sym->type);
3523 IC_RESULT (ic) = opr;
3525 /* misuse of parmBytes (normally used for functions)
3526 * to save estimated stack position of this argument.
3527 * Normally this should be zero for RECEIVE iCodes.
3528 * No idea if this causes side effects on other ports. - dw
3530 ic->parmBytes = paramByteCounter;
3532 /* what stack position do we have? */
3533 paramByteCounter += getSize (sym->type);
3542 /*-----------------------------------------------------------------*/
3543 /* geniCodeFunctionBody - create the function body */
3544 /*-----------------------------------------------------------------*/
3546 geniCodeFunctionBody (ast * tree,int lvl)
3553 /* reset the auto generation */
3559 func = ast2iCode (tree->left,lvl+1);
3560 fetype = getSpec (operandType (func));
3562 savelineno = lineno;
3563 lineno = OP_SYMBOL (func)->lineDef;
3564 /* create an entry label */
3565 geniCodeLabel (entryLabel);
3566 lineno = savelineno;
3568 /* create a proc icode */
3569 ic = newiCode (FUNCTION, func, NULL);
3570 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3575 /* for all parameters that are passed
3576 on registers add a "receive" */
3577 geniCodeReceive (tree->values.args, func);
3579 /* generate code for the body */
3580 ast2iCode (tree->right,lvl+1);
3582 /* create a label for return */
3583 geniCodeLabel (returnLabel);
3585 /* now generate the end proc */
3586 ic = newiCode (ENDFUNCTION, func, NULL);
3592 /*-----------------------------------------------------------------*/
3593 /* geniCodeReturn - gen icode for 'return' statement */
3594 /*-----------------------------------------------------------------*/
3596 geniCodeReturn (operand * op)
3600 /* if the operand is present force an rvalue */
3602 op = geniCodeRValue (op, FALSE);
3604 ic = newiCode (RETURN, op, NULL);
3608 /*-----------------------------------------------------------------*/
3609 /* geniCodeIfx - generates code for extended if statement */
3610 /*-----------------------------------------------------------------*/
3612 geniCodeIfx (ast * tree,int lvl)
3615 operand *condition = ast2iCode (tree->left,lvl+1);
3618 /* if condition is null then exit */
3622 condition = geniCodeRValue (condition, FALSE);
3624 cetype = getSpec (operandType (condition));
3625 /* if the condition is a literal */
3626 if (IS_LITERAL (cetype))
3628 if (floatFromVal (condition->operand.valOperand))
3630 if (tree->trueLabel)
3631 geniCodeGoto (tree->trueLabel);
3637 if (tree->falseLabel)
3638 geniCodeGoto (tree->falseLabel);
3643 if (tree->trueLabel)
3645 ic = newiCodeCondition (condition,
3650 if (tree->falseLabel)
3651 geniCodeGoto (tree->falseLabel);
3655 ic = newiCodeCondition (condition,
3662 ast2iCode (tree->right,lvl+1);
3665 /*-----------------------------------------------------------------*/
3666 /* geniCodeJumpTable - tries to create a jump table for switch */
3667 /*-----------------------------------------------------------------*/
3669 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3671 int min, max, cnt = 1;
3678 int needRangeCheck = !optimize.noJTabBoundary
3679 || tree->values.switchVals.swDefault;
3680 sym_link *cetype = getSpec (operandType (cond));
3681 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3682 int sizeofMatchJump, sizeofJumpTable;
3685 if (!tree || !caseVals)
3688 /* the criteria for creating a jump table is */
3689 /* all integer numbers between the maximum & minimum must */
3690 /* be present , the maximum value should not exceed 255 */
3691 /* If not all integer numbers are present the algorithm */
3692 /* inserts jumps to the default label for the missing numbers */
3693 /* and decides later whether it is worth it */
3694 min = (int) floatFromVal (vch = caseVals);
3701 max = (int) floatFromVal (vch);
3703 /* Exit if the range is too large to handle with a jump table. */
3704 if (1 + max - min > port->jumptableCost.maxCount)
3707 switch (getSize (operandType (cond)))
3709 case 1: sizeIndex = 0; break;
3710 case 2: sizeIndex = 1; break;
3711 case 4: sizeIndex = 2; break;
3715 /* Compute the size cost of the range check and subtraction. */
3717 sizeofZeroMinCost = 0;
3721 if (!(min==0 && IS_UNSIGNED (cetype)))
3722 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3723 if (!IS_UNSIGNED (cetype))
3724 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3725 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3728 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3730 /* If the size cost of handling a non-zero minimum exceeds the */
3731 /* cost of extending the range down to zero, then it might be */
3732 /* better to extend the range to zero. */
3733 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3734 >= (min * port->jumptableCost.sizeofElement))
3736 /* Only extend the jump table if it would still be manageable. */
3737 if (1 + max <= port->jumptableCost.maxCount)
3740 if (IS_UNSIGNED (cetype))
3743 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3747 /* Compute the total size cost of a jump table. */
3748 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3749 + port->jumptableCost.sizeofDispatch
3750 + sizeofMinCost + sizeofMaxCost;
3752 /* Compute the total size cost of a match & jump sequence */
3753 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3755 /* If the size cost of the jump table is uneconomical then exit */
3756 if (sizeofMatchJump < sizeofJumpTable)
3759 /* The jump table is preferable. */
3761 /* First, a label for the default or missing cases. */
3762 if (tree->values.switchVals.swDefault)
3764 SNPRINTF (buffer, sizeof(buffer),
3766 tree->values.switchVals.swNum);
3770 SNPRINTF (buffer, sizeof(buffer),
3772 tree->values.switchVals.swNum);
3774 falseLabel = newiTempLabel (buffer);
3776 /* Build the list of labels for the jump table. */
3778 t = (int) floatFromVal (vch);
3779 for (i=min; i<=max; i++)
3783 /* Explicit case: make a new label for it. */
3784 SNPRINTF (buffer, sizeof(buffer),
3786 tree->values.switchVals.swNum,
3788 addSet (&labels, newiTempLabel (buffer));
3791 t = (int) floatFromVal (vch);
3795 /* Implicit case: use the default label. */
3796 addSet (&labels, falseLabel);
3800 /* first we rule out the boundary conditions */
3801 /* if only optimization says so */
3804 sym_link *cetype = getSpec (operandType (cond));
3805 /* no need to check the lower bound if
3806 the condition is unsigned & minimum value is zero */
3807 if (!(min == 0 && IS_UNSIGNED (cetype)))
3809 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3810 ic = newiCodeCondition (boundary, falseLabel, NULL);
3814 /* now for upper bounds */
3815 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3816 ic = newiCodeCondition (boundary, falseLabel, NULL);
3820 /* if the min is not zero then we no make it zero */
3823 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3824 if (!IS_LITERAL(getSpec(operandType(cond))))
3825 setOperandType (cond, UCHARTYPE);
3828 /* now create the jumptable */
3829 ic = newiCode (JUMPTABLE, NULL, NULL);
3830 IC_JTCOND (ic) = cond;
3831 IC_JTLABELS (ic) = labels;
3836 /*-----------------------------------------------------------------*/
3837 /* geniCodeSwitch - changes a switch to a if statement */
3838 /*-----------------------------------------------------------------*/
3840 geniCodeSwitch (ast * tree,int lvl)
3843 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3844 value *caseVals = tree->values.switchVals.swVals;
3845 symbol *trueLabel, *falseLabel;
3847 /* If the condition is a literal, then just jump to the */
3848 /* appropriate case label. */
3849 if (IS_LITERAL(getSpec(operandType(cond))))
3851 int switchVal, caseVal;
3853 switchVal = (int) floatFromVal (cond->operand.valOperand);
3856 caseVal = (int) floatFromVal (caseVals);
3857 if (caseVal == switchVal)
3859 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3860 tree->values.switchVals.swNum, caseVal);
3861 trueLabel = newiTempLabel (buffer);
3862 geniCodeGoto (trueLabel);
3865 caseVals = caseVals->next;
3867 goto defaultOrBreak;
3870 /* If cond is volatile, it might change while we are trying to */
3871 /* find the matching case. To avoid this possibility, make a */
3872 /* non-volatile copy to use instead. */
3873 if (IS_OP_VOLATILE (cond))
3878 newcond = newiTempOperand (operandType (cond), TRUE);
3879 newcond->isvolatile = 0;
3880 ic = newiCode ('=', NULL, cond);
3881 IC_RESULT (ic) = newcond;
3886 /* if we can make this a jump table */
3887 if (geniCodeJumpTable (cond, caseVals, tree))
3888 goto jumpTable; /* no need for the comparison */
3890 /* for the cases defined do */
3894 operand *compare = geniCodeLogic (cond,
3895 operandFromValue (caseVals),
3898 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3899 tree->values.switchVals.swNum,
3900 (int) floatFromVal (caseVals));
3901 trueLabel = newiTempLabel (buffer);
3903 ic = newiCodeCondition (compare, trueLabel, NULL);
3905 caseVals = caseVals->next;
3910 /* if default is present then goto break else break */
3911 if (tree->values.switchVals.swDefault)
3913 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3917 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3920 falseLabel = newiTempLabel (buffer);
3921 geniCodeGoto (falseLabel);
3924 ast2iCode (tree->right,lvl+1);
3927 /*-----------------------------------------------------------------*/
3928 /* geniCodeInline - intermediate code for inline assembler */
3929 /*-----------------------------------------------------------------*/
3931 geniCodeInline (ast * tree)
3935 ic = newiCode (INLINEASM, NULL, NULL);
3936 IC_INLINE (ic) = tree->values.inlineasm;
3940 /*-----------------------------------------------------------------*/
3941 /* geniCodeArrayInit - intermediate code for array initializer */
3942 /*-----------------------------------------------------------------*/
3944 geniCodeArrayInit (ast * tree, operand *array)
3948 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3949 ic = newiCode (ARRAYINIT, array, NULL);
3950 IC_ARRAYILIST (ic) = tree->values.constlist;
3952 operand *left=newOperand(), *right=newOperand();
3953 left->type=right->type=SYMBOL;
3954 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3955 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3956 ic = newiCode (ARRAYINIT, left, right);
3961 /*-----------------------------------------------------------------*/
3962 /* geniCodeCritical - intermediate code for a critical statement */
3963 /*-----------------------------------------------------------------*/
3965 geniCodeCritical (ast *tree, int lvl)
3971 if (!options.stackAuto)
3973 type = newLink(SPECIFIER);
3974 SPEC_VOLATILE(type) = 1;
3975 SPEC_NOUN(type) = V_BIT;
3976 SPEC_SCLS(type) = S_BIT;
3977 SPEC_BLEN(type) = 1;
3978 SPEC_BSTR(type) = 0;
3979 op = newiTempOperand(type, 1);
3982 /* If op is NULL, the original interrupt state will saved on */
3983 /* the stack. Otherwise, it will be saved in op. */
3985 /* Generate a save of the current interrupt state & disable */
3986 ic = newiCode (CRITICAL, NULL, NULL);
3987 IC_RESULT (ic) = op;
3990 /* Generate the critical code sequence */
3991 if (tree->left && tree->left->type == EX_VALUE)
3992 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3994 ast2iCode (tree->left,lvl+1);
3996 /* Generate a restore of the original interrupt state */
3997 ic = newiCode (ENDCRITICAL, NULL, op);
4001 /*-----------------------------------------------------------------*/
4002 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
4003 /* particular case. Ie : assigning or dereferencing array or ptr */
4004 /*-----------------------------------------------------------------*/
4005 set * lvaluereqSet = NULL;
4006 typedef struct lvalItem
4013 /*-----------------------------------------------------------------*/
4014 /* addLvaluereq - add a flag for lvalreq for current ast level */
4015 /*-----------------------------------------------------------------*/
4016 void addLvaluereq(int lvl)
4018 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4021 addSetHead(&lvaluereqSet,lpItem);
4024 /*-----------------------------------------------------------------*/
4025 /* delLvaluereq - del a flag for lvalreq for current ast level */
4026 /*-----------------------------------------------------------------*/
4030 lpItem = getSet(&lvaluereqSet);
4031 if(lpItem) Safe_free(lpItem);
4033 /*-----------------------------------------------------------------*/
4034 /* clearLvaluereq - clear lvalreq flag */
4035 /*-----------------------------------------------------------------*/
4036 void clearLvaluereq()
4039 lpItem = peekSet(lvaluereqSet);
4040 if(lpItem) lpItem->req = 0;
4042 /*-----------------------------------------------------------------*/
4043 /* getLvaluereq - get the last lvalreq level */
4044 /*-----------------------------------------------------------------*/
4045 int getLvaluereqLvl()
4048 lpItem = peekSet(lvaluereqSet);
4049 if(lpItem) return lpItem->lvl;
4052 /*-----------------------------------------------------------------*/
4053 /* isLvaluereq - is lvalreq valid for this level ? */
4054 /*-----------------------------------------------------------------*/
4055 int isLvaluereq(int lvl)
4058 lpItem = peekSet(lvaluereqSet);
4059 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4063 /*-----------------------------------------------------------------*/
4064 /* ast2iCode - creates an icodeList from an ast */
4065 /*-----------------------------------------------------------------*/
4067 ast2iCode (ast * tree,int lvl)
4069 operand *left = NULL;
4070 operand *right = NULL;
4074 /* set the global variables for filename & line number */
4076 filename = tree->filename;
4078 lineno = tree->lineno;
4080 block = tree->block;
4082 scopeLevel = tree->level;
4084 seqPoint = tree->seqPoint;
4086 if (tree->type == EX_VALUE)
4087 return operandFromValue (tree->opval.val);
4089 if (tree->type == EX_LINK)
4090 return operandFromLink (tree->opval.lnk);
4092 /* if we find a nullop */
4093 if (tree->type == EX_OP &&
4094 (tree->opval.op == NULLOP ||
4095 tree->opval.op == BLOCK))
4097 if (tree->left && tree->left->type == EX_VALUE)
4098 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4100 ast2iCode (tree->left,lvl+1);
4101 if (tree->right && tree->right->type == EX_VALUE)
4102 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4104 ast2iCode (tree->right,lvl+1);
4108 /* special cases for not evaluating */
4109 if (tree->opval.op != ':' &&
4110 tree->opval.op != '?' &&
4111 tree->opval.op != CALL &&
4112 tree->opval.op != IFX &&
4113 tree->opval.op != AND_OP &&
4114 tree->opval.op != OR_OP &&
4115 tree->opval.op != LABEL &&
4116 tree->opval.op != GOTO &&
4117 tree->opval.op != SWITCH &&
4118 tree->opval.op != FUNCTION &&
4119 tree->opval.op != INLINEASM &&
4120 tree->opval.op != CRITICAL)
4123 if (IS_ASSIGN_OP (tree->opval.op) ||
4124 IS_DEREF_OP (tree) ||
4125 (tree->opval.op == '&' && !tree->right) ||
4126 tree->opval.op == PTR_OP)
4129 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4130 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4133 left = operandFromAst (tree->left,lvl);
4135 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4136 left = geniCodeRValue (left, TRUE);
4140 left = operandFromAst (tree->left,lvl);
4142 if (tree->opval.op == INC_OP ||
4143 tree->opval.op == DEC_OP)
4146 right = operandFromAst (tree->right,lvl);
4151 right = operandFromAst (tree->right,lvl);
4155 /* now depending on the type of operand */
4156 /* this will be a biggy */
4157 switch (tree->opval.op)
4160 case '[': /* array operation */
4162 //sym_link *ltype = operandType (left);
4163 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4164 left = geniCodeRValue (left, FALSE);
4165 right = geniCodeRValue (right, TRUE);
4168 return geniCodeArray (left, right,lvl);
4170 case '.': /* structure dereference */
4171 if (IS_PTR (operandType (left)))
4172 left = geniCodeRValue (left, TRUE);
4174 left = geniCodeRValue (left, FALSE);
4176 return geniCodeStruct (left, right, tree->lvalue);
4178 case PTR_OP: /* structure pointer dereference */
4181 pType = operandType (left);
4182 left = geniCodeRValue (left, TRUE);
4184 setOClass (pType, getSpec (operandType (left)));
4187 return geniCodeStruct (left, right, tree->lvalue);
4189 case INC_OP: /* increment operator */
4191 return geniCodePostInc (left);
4193 return geniCodePreInc (right, tree->lvalue);
4195 case DEC_OP: /* decrement operator */
4197 return geniCodePostDec (left);
4199 return geniCodePreDec (right, tree->lvalue);
4201 case '&': /* bitwise and or address of operator */
4203 { /* this is a bitwise operator */
4204 left = geniCodeRValue (left, FALSE);
4205 right = geniCodeRValue (right, FALSE);
4206 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4209 return geniCodeAddressOf (left);
4211 case '|': /* bitwise or & xor */
4213 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4214 geniCodeRValue (right, FALSE),
4219 return geniCodeDivision (geniCodeRValue (left, FALSE),
4220 geniCodeRValue (right, FALSE),
4221 getResultTypeFromType (tree->ftype));
4224 return geniCodeModulus (geniCodeRValue (left, FALSE),
4225 geniCodeRValue (right, FALSE),
4226 getResultTypeFromType (tree->ftype));
4229 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4230 geniCodeRValue (right, FALSE),
4231 getResultTypeFromType (tree->ftype));
4233 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4237 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4238 geniCodeRValue (right, FALSE),
4239 getResultTypeFromType (tree->ftype));
4241 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4245 return geniCodeAdd (geniCodeRValue (left, FALSE),
4246 geniCodeRValue (right, FALSE),
4247 getResultTypeFromType (tree->ftype),
4250 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4253 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4254 geniCodeRValue (right, FALSE),
4255 getResultTypeFromType (tree->ftype));
4258 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4259 geniCodeRValue (right, FALSE));
4261 #if 0 // this indeed needs a second thought
4265 // let's keep this simple: get the rvalue we need
4266 op=geniCodeRValue (right, FALSE);
4267 // now cast it to whatever we want
4268 op=geniCodeCast (operandType(left), op, FALSE);
4269 // if this is going to be used as an lvalue, make it so
4275 #else // bug #604575, is it a bug ????
4276 return geniCodeCast (operandType (left),
4277 geniCodeRValue (right, FALSE), FALSE);
4284 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4289 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4290 setOperandType (op, UCHARTYPE);
4297 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4298 geniCodeRValue (right, FALSE),
4300 setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4305 return geniCodeLogicAndOr (tree, lvl);
4312 /* different compilers (even different gccs) evaluate
4313 the two calls in a different order. to get the same
4314 result on all machines we've to specify a clear sequence.
4315 return geniCodeLogic (geniCodeRValue (left, FALSE),
4316 geniCodeRValue (right, FALSE),
4320 operand *leftOp, *rightOp;
4322 leftOp = geniCodeRValue (left , FALSE);
4323 rightOp = geniCodeRValue (right, FALSE);
4325 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4328 return geniCodeConditional (tree,lvl);
4331 return operandFromLit (getSize (tree->right->ftype));
4335 sym_link *rtype = operandType (right);
4336 sym_link *ltype = operandType (left);
4337 if (IS_PTR (rtype) && IS_ITEMP (right)
4338 && right->isaddr && compareType (rtype->next, ltype) == 1)
4339 right = geniCodeRValue (right, TRUE);
4341 right = geniCodeRValue (right, FALSE);
4343 geniCodeAssign (left, right, 0, 1);
4348 geniCodeAssign (left,
4349 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4351 geniCodeRValue (right, FALSE),
4352 getResultTypeFromType (tree->ftype)),
4357 geniCodeAssign (left,
4358 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4360 geniCodeRValue (right, FALSE),
4361 getResultTypeFromType (tree->ftype)),
4365 geniCodeAssign (left,
4366 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4368 geniCodeRValue (right, FALSE),
4369 getResultTypeFromType (tree->ftype)),
4373 sym_link *rtype = operandType (right);
4374 sym_link *ltype = operandType (left);
4375 if (IS_PTR (rtype) && IS_ITEMP (right)
4376 && right->isaddr && compareType (rtype->next, ltype) == 1)
4377 right = geniCodeRValue (right, TRUE);
4379 right = geniCodeRValue (right, FALSE);
4382 return geniCodeAssign (left,
4383 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4386 getResultTypeFromType (tree->ftype),
4392 sym_link *rtype = operandType (right);
4393 sym_link *ltype = operandType (left);
4394 if (IS_PTR (rtype) && IS_ITEMP (right)
4395 && right->isaddr && compareType (rtype->next, ltype) == 1)
4397 right = geniCodeRValue (right, TRUE);
4401 right = geniCodeRValue (right, FALSE);
4404 geniCodeAssign (left,
4405 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4408 getResultTypeFromType (tree->ftype)),
4413 geniCodeAssign (left,
4414 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4416 geniCodeRValue (right, FALSE),
4417 getResultTypeFromType (tree->ftype)),
4421 geniCodeAssign (left,
4422 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4424 geniCodeRValue (right, FALSE)), 0, 1);
4427 geniCodeAssign (left,
4428 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4430 geniCodeRValue (right, FALSE),
4432 operandType (left)), 0, 1);
4435 geniCodeAssign (left,
4436 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4438 geniCodeRValue (right, FALSE),
4440 operandType (left)), 0, 1);
4443 geniCodeAssign (left,
4444 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4446 geniCodeRValue (right, FALSE),
4448 operandType (left)), 0, 1);
4450 return geniCodeRValue (right, FALSE);
4453 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4456 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4457 return ast2iCode (tree->right,lvl+1);
4460 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4461 return ast2iCode (tree->right,lvl+1);
4464 geniCodeFunctionBody (tree,lvl);
4468 geniCodeReturn (right);
4472 geniCodeIfx (tree,lvl);
4476 geniCodeSwitch (tree,lvl);
4480 geniCodeInline (tree);
4484 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4488 geniCodeCritical (tree, lvl);
4494 /*-----------------------------------------------------------------*/
4495 /* reverseICChain - gets from the list and creates a linkedlist */
4496 /*-----------------------------------------------------------------*/
4503 while ((loop = getSet (&iCodeChain)))
4515 /*-----------------------------------------------------------------*/
4516 /* iCodeFromAst - given an ast will convert it to iCode */
4517 /*-----------------------------------------------------------------*/
4519 iCodeFromAst (ast * tree)
4521 returnLabel = newiTempLabel ("_return");
4522 entryLabel = newiTempLabel ("_entry");
4524 return reverseiCChain ();
4527 static const char *opTypeToStr(OPTYPE op)
4531 case SYMBOL: return "symbol";
4532 case VALUE: return "value";
4533 case TYPE: return "type";
4535 return "undefined type";
4539 operand *validateOpType(operand *op,
4546 if (op && op->type == type)
4551 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4552 " expected %s, got %s\n",
4553 macro, args, file, line,
4554 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4556 return op; // never reached, makes compiler happy.