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 /* newiTempPreheaderLabel - creates a new preheader label */
729 /*-----------------------------------------------------------------*/
731 newiTempPreheaderLabel ()
735 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
736 itmplbl = newSymbol (buffer, 1);
740 itmplbl->key = labelKey++;
741 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
746 /*-----------------------------------------------------------------*/
747 /* initiCode - initialises some iCode related stuff */
748 /*-----------------------------------------------------------------*/
755 /*-----------------------------------------------------------------*/
756 /* copyiCode - make a copy of the iCode given */
757 /*-----------------------------------------------------------------*/
759 copyiCode (iCode * ic)
761 iCode *nic = newiCode (ic->op, NULL, NULL);
763 nic->lineno = ic->lineno;
764 nic->filename = ic->filename;
765 nic->block = ic->block;
766 nic->level = ic->level;
767 nic->parmBytes = ic->parmBytes;
769 /* deal with the special cases first */
773 IC_COND (nic) = operandFromOperand (IC_COND (ic));
774 IC_TRUE (nic) = IC_TRUE (ic);
775 IC_FALSE (nic) = IC_FALSE (ic);
779 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
780 IC_JTLABELS (nic) = IC_JTLABELS (ic);
785 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
786 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
790 IC_INLINE (nic) = IC_INLINE (ic);
794 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
798 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
799 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
800 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
806 /*-----------------------------------------------------------------*/
807 /* getTableEntry - gets the table entry for the given operator */
808 /*-----------------------------------------------------------------*/
810 getTableEntry (int oper)
814 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
815 if (oper == codeTable[i].icode)
816 return &codeTable[i];
821 /*-----------------------------------------------------------------*/
822 /* newiTempOperand - new intermediate temp operand */
823 /*-----------------------------------------------------------------*/
825 newiTempOperand (sym_link * type, char throwType)
828 operand *op = newOperand ();
832 itmp = newiTemp (NULL);
834 etype = getSpec (type);
836 if (IS_LITERAL (etype))
839 /* copy the type information */
841 itmp->etype = getSpec (itmp->type = (throwType ? type :
842 copyLinkChain (type)));
843 if (IS_LITERAL (itmp->etype))
845 SPEC_SCLS (itmp->etype) = S_REGISTER;
846 SPEC_OCLS (itmp->etype) = reg;
849 op->operand.symOperand = itmp;
850 op->key = itmp->key = ++operandKey;
854 /*-----------------------------------------------------------------*/
855 /* operandType - returns the type chain for an operand */
856 /*-----------------------------------------------------------------*/
858 operandType (operand * op)
860 /* depending on type of operand */
865 return op->operand.valOperand->type;
868 return op->operand.symOperand->type;
871 return op->operand.typeOperand;
873 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
874 " operand type not known ");
875 assert (0); /* should never come here */
876 /* Just to keep the compiler happy */
877 return (sym_link *) 0;
881 /*-----------------------------------------------------------------*/
882 /* isParamterToCall - will return 1 if op is a parameter to args */
883 /*-----------------------------------------------------------------*/
885 isParameterToCall (value * args, operand * op)
889 wassert (IS_SYMOP(op));
894 isSymbolEqual (op->operand.symOperand, tval->sym))
901 /*-----------------------------------------------------------------*/
902 /* isOperandGlobal - return 1 if operand is a global variable */
903 /*-----------------------------------------------------------------*/
905 isOperandGlobal (operand * op)
914 (op->operand.symOperand->level == 0 ||
915 IS_STATIC (op->operand.symOperand->etype) ||
916 IS_EXTERN (op->operand.symOperand->etype))
923 /*-----------------------------------------------------------------*/
924 /* isOperandVolatile - return 1 if the operand is volatile */
925 /*-----------------------------------------------------------------*/
927 isOperandVolatile (operand * op, bool chkTemp)
932 if (IS_ITEMP (op) && !chkTemp)
935 opetype = getSpec (optype = operandType (op));
937 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
940 if (IS_VOLATILE (opetype))
945 /*-----------------------------------------------------------------*/
946 /* isOperandLiteral - returns 1 if an operand contains a literal */
947 /*-----------------------------------------------------------------*/
949 isOperandLiteral (operand * op)
956 opetype = getSpec (operandType (op));
958 if (IS_LITERAL (opetype))
964 /*-----------------------------------------------------------------*/
965 /* isOperandInFarSpace - will return true if operand is in farSpace */
966 /*-----------------------------------------------------------------*/
968 isOperandInFarSpace (operand * op)
978 if (!IS_TRUE_SYMOP (op))
981 etype = SPIL_LOC (op)->etype;
987 etype = getSpec (operandType (op));
989 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
992 /*-----------------------------------------------------------------*/
993 /* isOperandInPagedSpace - return true if operand is in pagedSpace */
994 /*-----------------------------------------------------------------*/
996 isOperandInPagedSpace (operand * op)
1006 if (!IS_TRUE_SYMOP (op))
1009 etype = SPIL_LOC (op)->etype;
1015 etype = getSpec (operandType (op));
1017 return (IN_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1020 /*------------------------------------------------------------------*/
1021 /* isOperandInDirSpace - will return true if operand is in dirSpace */
1022 /*------------------------------------------------------------------*/
1024 isOperandInDirSpace (operand * op)
1034 if (!IS_TRUE_SYMOP (op))
1037 etype = SPIL_LOC (op)->etype;
1043 etype = getSpec (operandType (op));
1045 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1048 /*--------------------------------------------------------------------*/
1049 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
1050 /*--------------------------------------------------------------------*/
1052 isOperandInCodeSpace (operand * op)
1062 etype = getSpec (operandType (op));
1064 if (!IS_TRUE_SYMOP (op))
1067 etype = SPIL_LOC (op)->etype;
1073 etype = getSpec (operandType (op));
1075 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1078 /*-----------------------------------------------------------------*/
1079 /* isOperandOnStack - will return true if operand is on stack */
1080 /*-----------------------------------------------------------------*/
1082 isOperandOnStack (operand * op)
1092 etype = getSpec (operandType (op));
1093 if (IN_STACK (etype) ||
1094 OP_SYMBOL(op)->onStack ||
1095 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1101 /*-----------------------------------------------------------------*/
1102 /* isOclsExpensive - will return true if accesses to an output */
1103 /* storage class are expensive */
1104 /*-----------------------------------------------------------------*/
1106 isOclsExpensive (struct memmap *oclass)
1108 if (port->oclsExpense)
1109 return port->oclsExpense (oclass) > 0;
1111 /* In the absence of port specific guidance, assume only */
1112 /* farspace is expensive. */
1113 return IN_FARSPACE (oclass);
1116 /*-----------------------------------------------------------------*/
1117 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1118 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1119 /*-----------------------------------------------------------------*/
1121 isiCodeInFunctionCall (iCode * ic)
1125 /* Find the next CALL/PCALL */
1128 if (lic->op == CALL || lic->op == PCALL)
1136 /* A function call was found. Scan backwards and see if an */
1137 /* IPUSH or SEND is encountered */
1140 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1142 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1150 /*-----------------------------------------------------------------*/
1151 /* operandLitValue - literal value of an operand */
1152 /*-----------------------------------------------------------------*/
1154 operandLitValue (operand * op)
1156 assert (isOperandLiteral (op));
1158 return floatFromVal (op->operand.valOperand);
1161 /*-----------------------------------------------------------------*/
1162 /* getBuiltInParms - returns parameters to a builtin functions */
1163 /*-----------------------------------------------------------------*/
1164 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1169 /* builtin functions uses only SEND for parameters */
1170 while (ic->op != CALL) {
1171 assert(ic->op == SEND && ic->builtinSEND);
1172 ic->generated = 1; /* mark the icode as generated */
1173 parms[*pcount] = IC_LEFT(ic);
1179 /* make sure this is a builtin function call */
1180 assert(IS_SYMOP(IC_LEFT(ic)));
1181 ftype = operandType(IC_LEFT(ic));
1182 assert(IFFUNC_ISBUILTIN(ftype));
1186 /*-----------------------------------------------------------------*/
1187 /* operandOperation - performs operations on operands */
1188 /*-----------------------------------------------------------------*/
1190 operandOperation (operand * left, operand * right,
1191 int op, sym_link * type)
1193 sym_link *let , *ret=NULL;
1194 operand *retval = (operand *) 0;
1196 assert (isOperandLiteral (left));
1197 let = getSpec(operandType(left));
1199 assert (isOperandLiteral (right));
1200 ret = getSpec(operandType(right));
1206 retval = operandFromValue (valCastLiteral (type,
1207 operandLitValue (left) +
1208 operandLitValue (right)));
1211 retval = operandFromValue (valCastLiteral (type,
1212 operandLitValue (left) -
1213 operandLitValue (right)));
1217 retval = operandFromValue (valCastLiteral (type,
1218 operandLitValue (left) *
1219 operandLitValue (right)));
1220 This could be all we've to do, but with gcc we've to take care about
1221 overflows. Two examples:
1222 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1223 significant bits are lost (52 in fraction, 63 bits would be
1224 necessary to keep full precision).
1225 If the resulting double value is greater than ULONG_MAX (resp.
1226 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1229 /* if it is not a specifier then we can assume that */
1230 /* it will be an unsigned long */
1231 if (IS_INT (type) ||
1234 /* long is handled here, because it can overflow with double */
1235 if (IS_LONG (type) ||
1237 /* signed and unsigned mul are the same, as long as the precision
1238 of the result isn't bigger than the precision of the operands. */
1239 retval = operandFromValue (valCastLiteral (type,
1240 (TYPE_UDWORD) operandLitValue (left) *
1241 (TYPE_UDWORD) operandLitValue (right)));
1242 else if (IS_UNSIGNED (type)) /* unsigned int */
1244 /* unsigned int is handled here in order to detect overflow */
1245 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1246 (TYPE_UWORD) operandLitValue (right);
1248 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1249 if (ul != (TYPE_UWORD) ul)
1252 else /* signed int */
1254 /* signed int is handled here in order to detect overflow */
1255 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1256 (TYPE_WORD) operandLitValue (right);
1258 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1259 if (l != (TYPE_WORD) l)
1264 /* all others go here: */
1265 retval = operandFromValue (valCastLiteral (type,
1266 operandLitValue (left) *
1267 operandLitValue (right)));
1270 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1272 werror (E_DIVIDE_BY_ZERO);
1278 if (IS_UNSIGNED (type))
1280 SPEC_USIGN (let) = 1;
1281 SPEC_USIGN (ret) = 1;
1282 retval = operandFromValue (valCastLiteral (type,
1283 (TYPE_UDWORD) operandLitValue (left) /
1284 (TYPE_UDWORD) operandLitValue (right)));
1288 retval = operandFromValue (valCastLiteral (type,
1289 operandLitValue (left) /
1290 operandLitValue (right)));
1295 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1297 werror (E_DIVIDE_BY_ZERO);
1302 if (IS_UNSIGNED (type))
1303 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1304 (TYPE_UDWORD) operandLitValue (right));
1306 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1307 (TYPE_DWORD) operandLitValue (right));
1311 /* The number of left shifts is always unsigned. Signed doesn't make
1312 sense here. Shifting by a negative number is impossible. */
1313 retval = operandFromValue (valCastLiteral (type,
1314 ((TYPE_UDWORD) operandLitValue (left) <<
1315 (TYPE_UDWORD) operandLitValue (right))));
1318 /* The number of right shifts is always unsigned. Signed doesn't make
1319 sense here. Shifting by a negative number is impossible. */
1320 if (IS_UNSIGNED(let))
1321 /* unsigned: logic shift right */
1322 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1323 (TYPE_UDWORD) operandLitValue (right));
1325 /* signed: arithmetic shift right */
1326 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1327 (TYPE_UDWORD) operandLitValue (right));
1330 if (IS_FLOAT (let) || IS_FLOAT (ret))
1332 retval = operandFromLit (operandLitValue (left) ==
1333 operandLitValue (right));
1335 else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
1337 retval = operandFromLit (operandLitValue (left) ==
1338 operandLitValue (right));
1342 /* this op doesn't care about signedness */
1345 l = (TYPE_UDWORD) operandLitValue (left);
1346 r = (TYPE_UDWORD) operandLitValue (right);
1347 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1348 neccessary to strip them to 16 bit.
1349 Literals are reduced to their cheapest type, therefore left and
1350 right might have different types. It's neccessary to find a
1351 common type: int (used for char too) or long */
1352 if (!IS_LONG (let) &&
1358 retval = operandFromLit (l == r);
1362 retval = operandFromLit (operandLitValue (left) <
1363 operandLitValue (right));
1366 retval = operandFromLit (operandLitValue (left) <=
1367 operandLitValue (right));
1370 retval = operandFromLit (operandLitValue (left) !=
1371 operandLitValue (right));
1374 retval = operandFromLit (operandLitValue (left) >
1375 operandLitValue (right));
1378 retval = operandFromLit (operandLitValue (left) >=
1379 operandLitValue (right));
1382 retval = operandFromValue (valCastLiteral (type,
1383 (TYPE_UDWORD)operandLitValue(left) &
1384 (TYPE_UDWORD)operandLitValue(right)));
1387 retval = operandFromValue (valCastLiteral (type,
1388 (TYPE_UDWORD)operandLitValue(left) |
1389 (TYPE_UDWORD)operandLitValue(right)));
1392 retval = operandFromValue (valCastLiteral (type,
1393 (TYPE_UDWORD)operandLitValue(left) ^
1394 (TYPE_UDWORD)operandLitValue(right)));
1397 retval = operandFromLit (operandLitValue (left) &&
1398 operandLitValue (right));
1401 retval = operandFromLit (operandLitValue (left) ||
1402 operandLitValue (right));
1406 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1408 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1414 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1416 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1421 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1422 (TYPE_UDWORD)operandLitValue(right)) & 1);
1425 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1426 (TYPE_UDWORD)operandLitValue(right)) & 0xFF);
1429 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1430 (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF);
1434 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1435 ((getSize (let) * 8) - 1)) & 1);
1439 retval = operandFromValue (valCastLiteral (type,
1440 -1 * operandLitValue (left)));
1444 retval = operandFromValue (valCastLiteral (type,
1446 operandLitValue (left))));
1450 retval = operandFromLit (!operandLitValue (left));
1454 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1455 " operandOperation invalid operator ");
1463 /*-----------------------------------------------------------------*/
1464 /* isOperandEqual - compares two operand & return 1 if they r = */
1465 /*-----------------------------------------------------------------*/
1467 isOperandEqual (operand * left, operand * right)
1469 /* if the pointers are equal then they are equal */
1473 /* if either of them null then false */
1474 if (!left || !right)
1477 if (left->type != right->type)
1480 if (IS_SYMOP (left) && IS_SYMOP (right))
1481 return left->key == right->key;
1483 /* if types are the same */
1487 return isSymbolEqual (left->operand.symOperand,
1488 right->operand.symOperand);
1490 return (compareType (left->operand.valOperand->type,
1491 right->operand.valOperand->type) &&
1492 (floatFromVal (left->operand.valOperand) ==
1493 floatFromVal (right->operand.valOperand)));
1495 if (compareType (left->operand.typeOperand,
1496 right->operand.typeOperand) == 1)
1503 /*-------------------------------------------------------------------*/
1504 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1505 /*-------------------------------------------------------------------*/
1507 isiCodeEqual (iCode * left, iCode * right)
1509 /* if the same pointer */
1513 /* if either of them null */
1514 if (!left || !right)
1517 /* if operand are the same */
1518 if (left->op == right->op)
1521 /* compare all the elements depending on type */
1522 if (left->op != IFX)
1524 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1526 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1532 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1534 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1536 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1545 /*-----------------------------------------------------------------*/
1546 /* newiTempFromOp - create a temp Operand with same attributes */
1547 /*-----------------------------------------------------------------*/
1549 newiTempFromOp (operand * op)
1559 nop = newiTempOperand (operandType (op), TRUE);
1560 nop->isaddr = op->isaddr;
1561 nop->isvolatile = op->isvolatile;
1562 nop->isGlobal = op->isGlobal;
1563 nop->isLiteral = op->isLiteral;
1564 nop->usesDefs = op->usesDefs;
1565 nop->isParm = op->isParm;
1569 /*-----------------------------------------------------------------*/
1570 /* operand from operand - creates an operand holder for the type */
1571 /*-----------------------------------------------------------------*/
1573 operandFromOperand (operand * op)
1579 nop = newOperand ();
1580 nop->type = op->type;
1581 nop->isaddr = op->isaddr;
1583 nop->isvolatile = op->isvolatile;
1584 nop->isGlobal = op->isGlobal;
1585 nop->isLiteral = op->isLiteral;
1586 nop->usesDefs = op->usesDefs;
1587 nop->isParm = op->isParm;
1592 nop->operand.symOperand = op->operand.symOperand;
1595 nop->operand.valOperand = op->operand.valOperand;
1598 nop->operand.typeOperand = op->operand.typeOperand;
1605 /*-----------------------------------------------------------------*/
1606 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1607 /*-----------------------------------------------------------------*/
1609 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1611 operand *nop = operandFromOperand (op);
1613 if (nop->type == SYMBOL)
1615 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1616 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1622 /*-----------------------------------------------------------------*/
1623 /* operandFromSymbol - creates an operand from a symbol */
1624 /*-----------------------------------------------------------------*/
1626 operandFromSymbol (symbol * sym)
1631 /* if the symbol's type is a literal */
1632 /* then it is an enumerator type */
1633 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1634 return operandFromValue (valFromType (sym->etype));
1637 sym->key = ++operandKey;
1639 /* if this an implicit variable, means struct/union */
1640 /* member so just return it */
1641 if (sym->implicit || IS_FUNC (sym->type))
1645 op->operand.symOperand = sym;
1647 op->isvolatile = isOperandVolatile (op, TRUE);
1648 op->isGlobal = isOperandGlobal (op);
1652 /* under the following conditions create a
1653 register equivalent for a local symbol */
1654 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1655 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1657 (!(options.model == MODEL_FLAT24)) ) &&
1658 options.stackAuto == 0)
1661 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1662 !IS_FUNC (sym->type) && /* not a function */
1663 !sym->_isparm && /* not a parameter */
1664 IS_AUTO (sym) && /* is a local auto variable */
1665 !sym->addrtaken && /* whose address has not been taken */
1666 !sym->reqv && /* does not already have a reg equivalence */
1667 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1668 !sym->islbl && /* not a label */
1669 ok /* farspace check */
1673 /* we will use it after all optimizations
1674 and before liveRange calculation */
1675 sym->reqv = newiTempOperand (sym->type, 0);
1676 sym->reqv->key = sym->key;
1677 OP_SYMBOL (sym->reqv)->prereqv = sym;
1678 OP_SYMBOL (sym->reqv)->key = sym->key;
1679 OP_SYMBOL (sym->reqv)->isreqv = 1;
1680 OP_SYMBOL (sym->reqv)->islocal = 1;
1681 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1682 SPIL_LOC (sym->reqv) = sym;
1685 if (!IS_AGGREGATE (sym->type))
1689 op->operand.symOperand = sym;
1692 op->isvolatile = isOperandVolatile (op, TRUE);
1693 op->isGlobal = isOperandGlobal (op);
1694 op->isPtr = IS_PTR (operandType (op));
1695 op->isParm = sym->_isparm;
1700 /* itemp = &[_symbol] */
1702 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1703 IC_LEFT (ic)->type = SYMBOL;
1704 IC_LEFT (ic)->operand.symOperand = sym;
1705 IC_LEFT (ic)->key = sym->key;
1706 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1707 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1708 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1711 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1712 if (IS_ARRAY (sym->type))
1714 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1715 IC_RESULT (ic)->isaddr = 0;
1718 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1722 return IC_RESULT (ic);
1725 /*-----------------------------------------------------------------*/
1726 /* operandFromValue - creates an operand from value */
1727 /*-----------------------------------------------------------------*/
1729 operandFromValue (value * val)
1733 /* if this is a symbol then do the symbol thing */
1735 return operandFromSymbol (val->sym);
1737 /* this is not a symbol */
1740 op->operand.valOperand = val;
1741 op->isLiteral = isOperandLiteral (op);
1745 /*-----------------------------------------------------------------*/
1746 /* operandFromLink - operand from typeChain */
1747 /*-----------------------------------------------------------------*/
1749 operandFromLink (sym_link * type)
1753 /* operand from sym_link */
1759 op->operand.typeOperand = copyLinkChain (type);
1763 /*-----------------------------------------------------------------*/
1764 /* operandFromLit - makes an operand from a literal value */
1765 /*-----------------------------------------------------------------*/
1767 operandFromLit (double i)
1769 return operandFromValue (valueFromLit (i));
1772 /*-----------------------------------------------------------------*/
1773 /* operandFromAst - creates an operand from an ast */
1774 /*-----------------------------------------------------------------*/
1776 operandFromAst (ast * tree,int lvl)
1782 /* depending on type do */
1786 return ast2iCode (tree,lvl+1);
1790 return operandFromValue (tree->opval.val);
1794 return operandFromLink (tree->opval.lnk);
1801 /* Just to keep the compiler happy */
1802 return (operand *) 0;
1805 /*-----------------------------------------------------------------*/
1806 /* setOperandType - sets the operand's type to the given type */
1807 /*-----------------------------------------------------------------*/
1809 setOperandType (operand * op, sym_link * type)
1811 /* depending on the type of operand */
1816 op->operand.valOperand->etype =
1817 getSpec (op->operand.valOperand->type =
1818 copyLinkChain (type));
1822 if (op->operand.symOperand->isitmp)
1823 op->operand.symOperand->etype =
1824 getSpec (op->operand.symOperand->type =
1825 copyLinkChain (type));
1827 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1828 "attempt to modify type of source");
1832 op->operand.typeOperand = copyLinkChain (type);
1838 /*-----------------------------------------------------------------*/
1839 /* Get size in byte of ptr need to access an array */
1840 /*-----------------------------------------------------------------*/
1842 getArraySizePtr (operand * op)
1844 sym_link *ltype = operandType(op);
1848 int size = getSize(ltype);
1849 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1854 sym_link *letype = getSpec(ltype);
1855 switch (PTR_TYPE (SPEC_OCLS (letype)))
1867 if (GPTRSIZE > FPTRSIZE)
1868 return (GPTRSIZE-1);
1879 /*-----------------------------------------------------------------*/
1880 /* perform "usual unary conversions" */
1881 /*-----------------------------------------------------------------*/
1884 usualUnaryConversions (operand * op)
1886 if (IS_INTEGRAL (operandType (op)))
1888 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1891 return geniCodeCast (INTTYPE, op, TRUE);
1898 /*-----------------------------------------------------------------*/
1899 /* perform "usual binary conversions" */
1900 /*-----------------------------------------------------------------*/
1903 usualBinaryConversions (operand ** op1, operand ** op2,
1904 RESULT_TYPE resultType, int op)
1907 sym_link *rtype = operandType (*op2);
1908 sym_link *ltype = operandType (*op1);
1910 ctype = computeType (ltype, rtype, resultType, op);
1917 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1919 /* one byte operations: keep signedness for code generator */
1927 *op1 = geniCodeCast (ctype, *op1, TRUE);
1928 *op2 = geniCodeCast (ctype, *op2, TRUE);
1933 /*-----------------------------------------------------------------*/
1934 /* geniCodeValueAtAddress - generate intermeditate code for value */
1936 /*-----------------------------------------------------------------*/
1938 geniCodeRValue (operand * op, bool force)
1941 sym_link *type = operandType (op);
1942 sym_link *etype = getSpec (type);
1944 /* if this is an array & already */
1945 /* an address then return this */
1946 if (IS_AGGREGATE (type) ||
1947 (IS_PTR (type) && !force && !op->isaddr))
1948 return operandFromOperand (op);
1950 /* if this is not an address then must be */
1951 /* rvalue already so return this one */
1955 /* if this is not a temp symbol then */
1956 if (!IS_ITEMP (op) &&
1958 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1960 op = operandFromOperand (op);
1965 if (IS_SPEC (type) &&
1966 IS_TRUE_SYMOP (op) &&
1967 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1968 (options.model == MODEL_FLAT24) ))
1970 op = operandFromOperand (op);
1975 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1976 if (IS_PTR (type) && op->isaddr && force)
1979 type = copyLinkChain (type);
1981 IC_RESULT (ic) = newiTempOperand (type, 1);
1982 IC_RESULT (ic)->isaddr = 0;
1984 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1988 return IC_RESULT (ic);
1991 /*-----------------------------------------------------------------*/
1992 /* geniCodeCast - changes the value from one type to another */
1993 /*-----------------------------------------------------------------*/
1995 geniCodeCast (sym_link * type, operand * op, bool implicit)
1999 sym_link *opetype = getSpec (optype = operandType (op));
2003 /* one of them has size zero then error */
2004 if (IS_VOID (optype))
2006 werror (E_CAST_ZERO);
2010 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
2012 geniCodeArray2Ptr (op);
2016 /* if the operand is already the desired type then do nothing */
2017 if (compareType (type, optype) == 1)
2020 /* if this is a literal then just change the type & return */
2021 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
2023 return operandFromValue (valCastLiteral (type,
2024 operandLitValue (op)));
2027 /* if casting to/from pointers, do some checking */
2028 if (IS_PTR(type)) { // to a pointer
2029 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
2030 if (IS_INTEGRAL(optype)) {
2031 // maybe this is NULL, than it's ok.
2032 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
2033 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
2034 // no way to set the storage
2035 if (IS_LITERAL(optype)) {
2036 werror(E_LITERAL_GENERIC);
2039 werror(E_NONPTR2_GENPTR);
2042 } else if (implicit) {
2043 werror(W_INTEGRAL2PTR_NOCAST);
2048 // shouldn't do that with float, array or structure unless to void
2049 if (!IS_VOID(getSpec(type)) &&
2050 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2051 werror(E_INCOMPAT_TYPES);
2055 } else { // from a pointer to a pointer
2056 if (IS_GENPTR(type) && IS_VOID(type->next))
2057 { // cast to void* is always allowed
2059 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2060 { // cast from void* is always allowed
2062 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2063 // if not a pointer to a function
2064 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2065 if (implicit) { // if not to generic, they have to match
2066 if (!IS_GENPTR(type) &&
2067 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2068 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2072 werror(E_INCOMPAT_PTYPES);
2079 } else { // to a non pointer
2080 if (IS_PTR(optype)) { // from a pointer
2081 if (implicit) { // sneaky
2082 if (IS_INTEGRAL(type)) {
2083 werror(W_PTR2INTEGRAL_NOCAST);
2085 } else { // shouldn't do that with float, array or structure
2086 werror(E_INCOMPAT_TYPES);
2093 printFromToType (optype, type);
2096 /* if they are the same size create an assignment */
2098 /* This seems very dangerous to me, since there are several */
2099 /* optimizations (for example, gcse) that don't notice the */
2100 /* cast hidden in this assignement and may simplify an */
2101 /* iCode to use the original (uncasted) operand. */
2102 /* Unfortunately, other things break when this cast is */
2103 /* made explicit. Need to fix this someday. */
2104 /* -- EEP, 2004/01/21 */
2105 if (getSize (type) == getSize (optype) &&
2106 !IS_BITFIELD (type) &&
2108 !IS_FLOAT (optype) &&
2110 !IS_FIXED (optype) &&
2111 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2112 (!IS_SPEC (type) && !IS_SPEC (optype))))
2114 ic = newiCode ('=', NULL, op);
2115 IC_RESULT (ic) = newiTempOperand (type, 0);
2116 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2117 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2118 IC_RESULT (ic)->isaddr = 0;
2122 ic = newiCode (CAST, operandFromLink (type),
2123 geniCodeRValue (op, FALSE));
2125 IC_RESULT (ic) = newiTempOperand (type, 0);
2128 /* preserve the storage class & output class */
2129 /* of the original variable */
2130 restype = getSpec (operandType (IC_RESULT (ic)));
2131 if (!IS_LITERAL(opetype) &&
2134 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2135 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2138 return IC_RESULT (ic);
2141 /*-----------------------------------------------------------------*/
2142 /* geniCodeLabel - will create a Label */
2143 /*-----------------------------------------------------------------*/
2145 geniCodeLabel (symbol * label)
2149 ic = newiCodeLabelGoto (LABEL, label);
2153 /*-----------------------------------------------------------------*/
2154 /* geniCodeGoto - will create a Goto */
2155 /*-----------------------------------------------------------------*/
2157 geniCodeGoto (symbol * label)
2161 ic = newiCodeLabelGoto (GOTO, label);
2165 /*-----------------------------------------------------------------*/
2166 /* geniCodeMultiply - gen intermediate code for multiplication */
2167 /*-----------------------------------------------------------------*/
2169 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2176 /* if they are both literal then we know the result */
2177 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2178 return operandFromValue (valMult (left->operand.valOperand,
2179 right->operand.valOperand));
2181 if (IS_LITERAL(retype)) {
2182 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2185 resType = usualBinaryConversions (&left, &right, resultType, '*');
2187 rtype = operandType (right);
2188 retype = getSpec (rtype);
2189 ltype = operandType (left);
2190 letype = getSpec (ltype);
2193 /* if the right is a literal & power of 2 */
2194 /* then make it a left shift */
2195 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2196 efficient in most cases than 2 bytes result = 2 bytes << literal
2197 if port has 1 byte muldiv */
2198 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2199 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2200 && (port->support.muldiv == 1))
2201 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2202 && strcmp (port->target, "pic14") != 0)
2204 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2206 /* LEFT_OP need same size for left and result, */
2207 left = geniCodeCast (resType, left, TRUE);
2208 ltype = operandType (left);
2210 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2214 ic = newiCode ('*', left, right); /* normal multiplication */
2215 /* if the size left or right > 1 then support routine */
2216 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2220 IC_RESULT (ic) = newiTempOperand (resType, 1);
2223 return IC_RESULT (ic);
2226 /*-----------------------------------------------------------------*/
2227 /* geniCodeDivision - gen intermediate code for division */
2228 /*-----------------------------------------------------------------*/
2230 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2235 sym_link *rtype = operandType (right);
2236 sym_link *retype = getSpec (rtype);
2237 sym_link *ltype = operandType (left);
2238 sym_link *letype = getSpec (ltype);
2240 resType = usualBinaryConversions (&left, &right, resultType, '/');
2242 /* if the right is a literal & power of 2
2243 and left is unsigned then make it a
2245 if (IS_LITERAL (retype) &&
2246 !IS_FLOAT (letype) &&
2247 !IS_FIXED (letype) &&
2248 IS_UNSIGNED(letype) &&
2249 ((p2 = powof2 ((TYPE_UDWORD)
2250 floatFromVal (right->operand.valOperand))) > 0)) {
2251 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2255 ic = newiCode ('/', left, right); /* normal division */
2256 /* if the size left or right > 1 then support routine */
2257 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2260 IC_RESULT (ic) = newiTempOperand (resType, 0);
2263 return IC_RESULT (ic);
2265 /*-----------------------------------------------------------------*/
2266 /* geniCodeModulus - gen intermediate code for modulus */
2267 /*-----------------------------------------------------------------*/
2269 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2275 /* if they are both literal then we know the result */
2276 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2277 return operandFromValue (valMod (left->operand.valOperand,
2278 right->operand.valOperand));
2280 resType = usualBinaryConversions (&left, &right, resultType, '%');
2282 /* now they are the same size */
2283 ic = newiCode ('%', left, right);
2285 /* if the size left or right > 1 then support routine */
2286 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2288 IC_RESULT (ic) = newiTempOperand (resType, 0);
2291 return IC_RESULT (ic);
2294 /*-----------------------------------------------------------------*/
2295 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2296 /*-----------------------------------------------------------------*/
2298 geniCodePtrPtrSubtract (operand * left, operand * right)
2304 /* if they are both literals then */
2305 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2307 result = operandFromValue (valMinus (left->operand.valOperand,
2308 right->operand.valOperand));
2312 ic = newiCode ('-', left, right);
2314 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2318 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2322 // should we really do this? is this ANSI?
2323 return geniCodeDivision (result,
2324 operandFromLit (getSize (ltype->next)),
2328 /*-----------------------------------------------------------------*/
2329 /* geniCodeSubtract - generates code for subtraction */
2330 /*-----------------------------------------------------------------*/
2332 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2339 /* if they both pointers then */
2340 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2341 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2342 return geniCodePtrPtrSubtract (left, right);
2344 /* if they are both literal then we know the result */
2345 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2346 && left->isLiteral && right->isLiteral)
2347 return operandFromValue (valMinus (left->operand.valOperand,
2348 right->operand.valOperand));
2350 /* if left is an array or pointer */
2351 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2353 isarray = left->isaddr;
2354 right = geniCodeMultiply (right,
2355 operandFromLit (getSize (ltype->next)),
2356 (getArraySizePtr(left) >= INTSIZE) ?
2359 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2362 { /* make them the same size */
2363 resType = usualBinaryConversions (&left, &right, resultType, '-');
2366 ic = newiCode ('-', left, right);
2368 IC_RESULT (ic) = newiTempOperand (resType, 1);
2369 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2371 /* if left or right is a float */
2372 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2373 || IS_FIXED (ltype) || IS_FIXED (rtype))
2377 return IC_RESULT (ic);
2380 /*-----------------------------------------------------------------*/
2381 /* geniCodeAdd - generates iCode for addition */
2382 /*-----------------------------------------------------------------*/
2384 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2393 /* if the right side is LITERAL zero */
2394 /* return the left side */
2395 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2398 /* if left is literal zero return right */
2399 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2402 /* if left is a pointer then size */
2403 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2405 isarray = left->isaddr;
2406 // there is no need to multiply with 1
2407 if (getSize (ltype->next) != 1)
2409 size = operandFromLit (getSize (ltype->next));
2410 SPEC_USIGN (getSpec (operandType (size))) = 1;
2411 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2412 right = geniCodeMultiply (right,
2414 (getArraySizePtr(left) >= INTSIZE) ?
2417 /* Even if right is a 'unsigned char',
2418 the result will be a 'signed int' due to the promotion rules.
2419 It doesn't make sense when accessing arrays, so let's fix it here: */
2421 SPEC_USIGN (getSpec (operandType (right))) = 1;
2423 resType = copyLinkChain (ltype);
2426 { // make them the same size
2427 resType = usualBinaryConversions (&left, &right, resultType, '+');
2430 /* if they are both literals then we know */
2431 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2432 && left->isLiteral && right->isLiteral)
2433 return operandFromValue (valPlus (valFromType (ltype),
2434 valFromType (rtype)));
2436 ic = newiCode ('+', left, right);
2438 IC_RESULT (ic) = newiTempOperand (resType, 1);
2439 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2441 /* if left or right is a float then support
2443 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2444 || IS_FIXED (ltype) || IS_FIXED (rtype))
2449 return IC_RESULT (ic);
2453 /*-----------------------------------------------------------------*/
2454 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2455 /*-----------------------------------------------------------------*/
2457 aggrToPtr (sym_link * type, bool force)
2462 if (IS_PTR (type) && !force)
2465 etype = getSpec (type);
2466 ptype = newLink (DECLARATOR);
2470 /* set the pointer depending on the storage class */
2471 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2475 /*------------------------------------------------------------------*/
2476 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2477 /*------------------------------------------------------------------*/
2479 aggrToPtrDclType (sym_link * type, bool force)
2481 if (IS_PTR (type) && !force)
2482 return DCL_TYPE (type);
2484 /* return the pointer depending on the storage class */
2485 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2488 /*-----------------------------------------------------------------*/
2489 /* geniCodeArray2Ptr - array to pointer */
2490 /*-----------------------------------------------------------------*/
2492 geniCodeArray2Ptr (operand * op)
2494 sym_link *optype = operandType (op);
2495 sym_link *opetype = getSpec (optype);
2497 /* set the pointer depending on the storage class */
2498 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2505 /*-----------------------------------------------------------------*/
2506 /* geniCodeArray - array access */
2507 /*-----------------------------------------------------------------*/
2509 geniCodeArray (operand * left, operand * right, int lvl)
2513 sym_link *ltype = operandType (left);
2518 if (IS_PTR (ltype->next) && left->isaddr)
2520 left = geniCodeRValue (left, FALSE);
2523 return geniCodeDerefPtr (geniCodeAdd (left,
2525 (getArraySizePtr(left) >= INTSIZE) ?
2531 size = operandFromLit (getSize (ltype->next));
2532 SPEC_USIGN (getSpec (operandType (size))) = 1;
2533 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2534 right = geniCodeMultiply (right,
2536 (getArraySizePtr(left) >= INTSIZE) ?
2539 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2540 It doesn't make sense when accessing arrays, so let's fix it here: */
2542 SPEC_USIGN (getSpec (operandType (right))) = 1;
2543 /* we can check for limits here */
2544 /* already done in SDCCast.c
2545 if (isOperandLiteral (right) &&
2548 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2550 werror (W_IDX_OUT_OF_BOUNDS,
2551 (int) operandLitValue (right) / getSize (ltype->next),
2556 ic = newiCode ('+', left, right);
2558 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2559 !IS_AGGREGATE (ltype->next) &&
2560 !IS_PTR (ltype->next))
2561 ? ltype : ltype->next), 0);
2563 if (!IS_AGGREGATE (ltype->next))
2565 IC_RESULT (ic)->isaddr = 1;
2566 IC_RESULT (ic)->aggr2ptr = 1;
2570 return IC_RESULT (ic);
2573 /*-----------------------------------------------------------------*/
2574 /* geniCodeStruct - generates intermediate code for structures */
2575 /*-----------------------------------------------------------------*/
2577 geniCodeStruct (operand * left, operand * right, bool islval)
2580 sym_link *type = operandType (left);
2581 sym_link *etype = getSpec (type);
2583 symbol *element = getStructElement (SPEC_STRUCT (etype),
2584 right->operand.symOperand);
2586 wassert(IS_SYMOP(right));
2588 /* add the offset */
2589 ic = newiCode ('+', left, operandFromLit (element->offset));
2591 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2593 /* preserve the storage & output class of the struct */
2594 /* as well as the volatile attribute */
2595 retype = getSpec (operandType (IC_RESULT (ic)));
2596 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2597 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2598 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2599 SPEC_CONST (retype) |= SPEC_CONST (etype);
2601 if (IS_PTR (element->type))
2602 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2604 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2607 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2610 /*-----------------------------------------------------------------*/
2611 /* geniCodePostInc - generate int code for Post increment */
2612 /*-----------------------------------------------------------------*/
2614 geniCodePostInc (operand * op)
2618 sym_link *optype = operandType (op);
2620 operand *rv = (IS_ITEMP (op) ?
2621 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2623 sym_link *rvtype = operandType (rv);
2626 /* if this is not an address we have trouble */
2629 werror (E_LVALUE_REQUIRED, "++");
2633 rOp = newiTempOperand (rvtype, 0);
2634 OP_SYMBOL(rOp)->noSpilLoc = 1;
2637 OP_SYMBOL(rv)->noSpilLoc = 1;
2639 geniCodeAssign (rOp, rv, 0, 0);
2641 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2643 werror(W_SIZEOF_VOID);
2644 if (IS_FLOAT (rvtype))
2645 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2646 else if (IS_FIXED16X16 (rvtype))
2647 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2649 ic = newiCode ('+', rv, operandFromLit (size));
2651 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2654 geniCodeAssign (op, result, 0, 0);
2660 /*-----------------------------------------------------------------*/
2661 /* geniCodePreInc - generate code for preIncrement */
2662 /*-----------------------------------------------------------------*/
2664 geniCodePreInc (operand * op, bool lvalue)
2667 sym_link *optype = operandType (op);
2668 operand *rop = (IS_ITEMP (op) ?
2669 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2671 sym_link *roptype = operandType (rop);
2677 werror (E_LVALUE_REQUIRED, "++");
2681 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2683 werror(W_SIZEOF_VOID);
2684 if (IS_FLOAT (roptype))
2685 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2686 else if (IS_FIXED16X16 (roptype))
2687 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2689 ic = newiCode ('+', rop, operandFromLit (size));
2690 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2693 (void) geniCodeAssign (op, result, 0, 0);
2694 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2700 /*-----------------------------------------------------------------*/
2701 /* geniCodePostDec - generates code for Post decrement */
2702 /*-----------------------------------------------------------------*/
2704 geniCodePostDec (operand * op)
2708 sym_link *optype = operandType (op);
2710 operand *rv = (IS_ITEMP (op) ?
2711 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2713 sym_link *rvtype = operandType (rv);
2716 /* if this is not an address we have trouble */
2719 werror (E_LVALUE_REQUIRED, "--");
2723 rOp = newiTempOperand (rvtype, 0);
2724 OP_SYMBOL(rOp)->noSpilLoc = 1;
2727 OP_SYMBOL(rv)->noSpilLoc = 1;
2729 geniCodeAssign (rOp, rv, 0, 0);
2731 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2733 werror(W_SIZEOF_VOID);
2734 if (IS_FLOAT (rvtype))
2735 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2736 else if (IS_FIXED16X16 (rvtype))
2737 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2739 ic = newiCode ('-', rv, operandFromLit (size));
2741 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2744 geniCodeAssign (op, result, 0, 0);
2750 /*-----------------------------------------------------------------*/
2751 /* geniCodePreDec - generate code for pre decrement */
2752 /*-----------------------------------------------------------------*/
2754 geniCodePreDec (operand * op, bool lvalue)
2757 sym_link *optype = operandType (op);
2758 operand *rop = (IS_ITEMP (op) ?
2759 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2761 sym_link *roptype = operandType (rop);
2767 werror (E_LVALUE_REQUIRED, "--");
2771 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2773 werror(W_SIZEOF_VOID);
2774 if (IS_FLOAT (roptype))
2775 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2776 else if (IS_FIXED16X16 (roptype))
2777 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2779 ic = newiCode ('-', rop, operandFromLit (size));
2780 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2783 (void) geniCodeAssign (op, result, 0, 0);
2784 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2791 /*-----------------------------------------------------------------*/
2792 /* geniCodeBitwise - gen int code for bitWise operators */
2793 /*-----------------------------------------------------------------*/
2795 geniCodeBitwise (operand * left, operand * right,
2796 int oper, sym_link * resType)
2800 left = geniCodeCast (resType, left, TRUE);
2801 right = geniCodeCast (resType, right, TRUE);
2803 ic = newiCode (oper, left, right);
2804 IC_RESULT (ic) = newiTempOperand (resType, 0);
2807 return IC_RESULT (ic);
2810 /*-----------------------------------------------------------------*/
2811 /* geniCodeAddressOf - gens icode for '&' address of operator */
2812 /*-----------------------------------------------------------------*/
2814 geniCodeAddressOf (operand * op)
2818 sym_link *optype = operandType (op);
2819 sym_link *opetype = getSpec (optype);
2821 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2823 op = operandFromOperand (op);
2828 /* lvalue check already done in decorateType */
2829 /* this must be a lvalue */
2830 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2831 /* werror (E_LVALUE_REQUIRED,"&"); */
2835 p = newLink (DECLARATOR);
2837 /* set the pointer depending on the storage class */
2838 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2840 p->next = copyLinkChain (optype);
2842 /* if already a temp */
2845 setOperandType (op, p);
2850 /* other wise make this of the type coming in */
2851 ic = newiCode (ADDRESS_OF, op, NULL);
2852 IC_RESULT (ic) = newiTempOperand (p, 1);
2853 IC_RESULT (ic)->isaddr = 0;
2855 return IC_RESULT (ic);
2858 /*-----------------------------------------------------------------*/
2859 /* setOClass - sets the output class depending on the pointer type */
2860 /*-----------------------------------------------------------------*/
2862 setOClass (sym_link * ptr, sym_link * spec)
2864 switch (DCL_TYPE (ptr))
2867 SPEC_OCLS (spec) = data;
2871 SPEC_OCLS (spec) = generic;
2875 SPEC_OCLS (spec) = xdata;
2879 SPEC_OCLS (spec) = code;
2883 SPEC_OCLS (spec) = idata;
2887 SPEC_OCLS (spec) = xstack;
2891 SPEC_OCLS (spec) = eeprom;
2900 /*-----------------------------------------------------------------*/
2901 /* geniCodeDerefPtr - dereference pointer with '*' */
2902 /*-----------------------------------------------------------------*/
2904 geniCodeDerefPtr (operand * op,int lvl)
2906 sym_link *rtype, *retype;
2907 sym_link *optype = operandType (op);
2909 // if this is an array then array access
2910 if (IS_ARRAY (optype)) {
2911 // don't worry, this will be optimized out later
2912 return geniCodeArray (op, operandFromLit (0), lvl);
2915 // just in case someone screws up
2916 wassert (IS_PTR (optype));
2918 if (IS_TRUE_SYMOP (op))
2921 op = geniCodeRValue (op, TRUE);
2924 /* now get rid of the pointer part */
2925 if (isLvaluereq(lvl) && IS_ITEMP (op))
2927 retype = getSpec (rtype = copyLinkChain (optype));
2931 retype = getSpec (rtype = copyLinkChain (optype->next));
2932 /* outputclass needs 2b updated */
2933 setOClass (optype, retype);
2936 op->isGptr = IS_GENPTR (optype);
2938 op->isaddr = (IS_PTR (rtype) ||
2939 IS_STRUCT (rtype) ||
2945 if (!isLvaluereq(lvl))
2946 op = geniCodeRValue (op, TRUE);
2948 setOperandType (op, rtype);
2953 /*-----------------------------------------------------------------*/
2954 /* geniCodeUnaryMinus - does a unary minus of the operand */
2955 /*-----------------------------------------------------------------*/
2957 geniCodeUnaryMinus (operand * op)
2960 sym_link *optype = operandType (op);
2962 if (IS_LITERAL (optype))
2963 return operandFromLit (-floatFromVal (op->operand.valOperand));
2965 ic = newiCode (UNARYMINUS, op, NULL);
2966 IC_RESULT (ic) = newiTempOperand (optype, 0);
2968 return IC_RESULT (ic);
2971 /*-----------------------------------------------------------------*/
2972 /* geniCodeLeftShift - gen i code for left shift */
2973 /*-----------------------------------------------------------------*/
2975 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2980 ic = newiCode (LEFT_OP, left, right);
2982 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2983 IC_RESULT (ic) = newiTempOperand (resType, 0);
2985 return IC_RESULT (ic);
2988 /*-----------------------------------------------------------------*/
2989 /* geniCodeRightShift - gen i code for right shift */
2990 /*-----------------------------------------------------------------*/
2992 geniCodeRightShift (operand * left, operand * right)
2996 ic = newiCode (RIGHT_OP, left, right);
2997 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2999 return IC_RESULT (ic);
3002 /*-----------------------------------------------------------------*/
3003 /* geniCodeLogic- logic code */
3004 /*-----------------------------------------------------------------*/
3006 geniCodeLogic (operand * left, operand * right, int op)
3010 sym_link *rtype = operandType (right);
3011 sym_link *ltype = operandType (left);
3013 /* left is integral type and right is literal then
3014 check if the literal value is within bounds */
3015 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3017 checkConstantRange(ltype,
3018 OP_VALUE(right), "compare operation", 1);
3021 /* if one operand is a pointer and the other is a literal generic void pointer,
3022 change the type of the literal generic void pointer to match the other pointer */
3023 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3024 && IS_PTR (rtype) && !IS_GENPTR(rtype))
3026 /* find left's definition */
3027 ic = (iCode *) setFirstItem (iCodeChain);
3030 if (((ic->op == CAST) || (ic->op == '='))
3031 && isOperandEqual(left, IC_RESULT (ic)))
3034 ic = setNextItem (iCodeChain);
3036 /* if casting literal to generic pointer, then cast to rtype instead */
3037 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3039 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3040 ltype = operandType(left);
3043 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3044 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3046 /* find right's definition */
3047 ic = (iCode *) setFirstItem (iCodeChain);
3050 if (((ic->op == CAST) || (ic->op == '='))
3051 && isOperandEqual(right, IC_RESULT (ic)))
3054 ic = setNextItem (iCodeChain);
3056 /* if casting literal to generic pointer, then cast to rtype instead */
3057 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3059 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3060 rtype = operandType(right);
3064 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3066 ic = newiCode (op, left, right);
3067 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3069 /* if comparing float
3070 and not a '==' || '!=' || '&&' || '||' (these
3072 if (IS_FLOAT(ctype) &&
3079 /* if comparing a fixed type use support functions */
3080 if (IS_FIXED(ctype))
3084 return IC_RESULT (ic);
3087 /*-----------------------------------------------------------------*/
3088 /* geniCodeLogicAndOr - && || operations */
3089 /*-----------------------------------------------------------------*/
3091 geniCodeLogicAndOr (ast *tree, int lvl)
3095 symbol *falseLabel = newiTempLabel (NULL);
3096 symbol *trueLabel = newiTempLabel (NULL);
3097 symbol *exitLabel = newiTempLabel (NULL);
3098 operand *op, *result, *condition;
3100 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3101 They can be reenabled by executing the following block. If you find
3102 a decent optimization you could start right here:
3107 operand *leftOp, *rightOp;
3109 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3110 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3112 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3116 /* generate two IFX for the '&&' or '||' op */
3118 /* evaluate left operand */
3119 condition = ast2iCode (tree->left, lvl + 1);
3120 op = geniCodeRValue (condition, FALSE);
3122 /* test left operand */
3123 if (tree->opval.op == AND_OP)
3124 ic = newiCodeCondition (op, NULL, falseLabel);
3126 ic = newiCodeCondition (op, trueLabel, NULL);
3129 /* evaluate right operand */
3130 condition = ast2iCode (tree->right, lvl + 1);
3131 op = geniCodeRValue (condition, FALSE);
3133 /* test right operand */
3134 ic = newiCodeCondition (op, trueLabel, NULL);
3137 /* store 0 or 1 in result */
3138 type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3139 result = newiTempOperand (type, 1);
3141 geniCodeLabel (falseLabel);
3142 geniCodeAssign (result, operandFromLit (0), 0, 0);
3143 /* generate an unconditional goto */
3144 geniCodeGoto (exitLabel);
3146 geniCodeLabel (trueLabel);
3147 geniCodeAssign (result, operandFromLit (1), 0, 0);
3149 geniCodeLabel (exitLabel);
3154 /*-----------------------------------------------------------------*/
3155 /* geniCodeUnary - for a generic unary operation */
3156 /*-----------------------------------------------------------------*/
3158 geniCodeUnary (operand * op, int oper)
3160 iCode *ic = newiCode (oper, op, NULL);
3162 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3164 return IC_RESULT (ic);
3167 /*-----------------------------------------------------------------*/
3168 /* geniCodeBinary - for a generic binary operation */
3169 /*-----------------------------------------------------------------*/
3171 geniCodeBinary (operand * left, operand * right, int oper)
3173 iCode *ic = newiCode (oper, left, right);
3175 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3177 return IC_RESULT (ic);
3180 /*-----------------------------------------------------------------*/
3181 /* geniCodeConditional - geniCode for '?' ':' operation */
3182 /*-----------------------------------------------------------------*/
3184 geniCodeConditional (ast * tree,int lvl)
3187 symbol *falseLabel = newiTempLabel (NULL);
3188 symbol *exitLabel = newiTempLabel (NULL);
3189 operand *cond = ast2iCode (tree->left,lvl+1);
3190 operand *true, *false, *result;
3192 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3196 true = ast2iCode (tree->right->left,lvl+1);
3198 /* move the value to a new Operand */
3199 result = newiTempOperand (tree->right->ftype, 0);
3200 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3202 /* generate an unconditional goto */
3203 geniCodeGoto (exitLabel);
3205 /* now for the right side */
3206 geniCodeLabel (falseLabel);
3208 false = ast2iCode (tree->right->right,lvl+1);
3209 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3211 /* create the exit label */
3212 geniCodeLabel (exitLabel);
3217 /*-----------------------------------------------------------------*/
3218 /* geniCodeAssign - generate code for assignment */
3219 /*-----------------------------------------------------------------*/
3221 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3224 sym_link *ltype = operandType (left);
3225 sym_link *rtype = operandType (right);
3227 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3229 werror (E_LVALUE_REQUIRED, "assignment");
3233 /* left is integral type and right is literal then
3234 check if the literal value is within bounds */
3235 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3237 checkConstantRange(ltype,
3238 OP_VALUE(right), "= operation", 0);
3241 /* if the left & right type don't exactly match */
3242 /* if pointer set then make sure the check is
3243 done with the type & not the pointer */
3244 /* then cast rights type to left */
3246 /* first check the type for pointer assignement */
3247 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3248 compareType (ltype, rtype) <= 0)
3250 if (compareType (ltype->next, rtype) < 0)
3251 right = geniCodeCast (ltype->next, right, TRUE);
3253 else if (compareType (ltype, rtype) < 0)
3254 right = geniCodeCast (ltype, right, TRUE);
3256 /* If left is a true symbol & ! volatile
3257 create an assignment to temporary for
3258 the right & then assign this temporary
3259 to the symbol. This is SSA (static single
3260 assignment). Isn't it simple and folks have
3261 published mountains of paper on it */
3262 if (IS_TRUE_SYMOP (left) &&
3263 !isOperandVolatile (left, FALSE) &&
3264 isOperandGlobal (left))
3269 if (IS_TRUE_SYMOP (right))
3270 sym = OP_SYMBOL (right);
3271 ic = newiCode ('=', NULL, right);
3272 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3273 /* avoid double fetch from volatile right, see bug 1369874 */
3274 if (!isOperandVolatile (right, FALSE))
3275 SPIL_LOC (newRight) = sym;
3280 ic = newiCode ('=', NULL, right);
3281 IC_RESULT (ic) = left;
3284 /* if left isgptr flag is set then support
3285 routine will be required */
3289 ic->nosupdate = nosupdate;
3293 /*-----------------------------------------------------------------*/
3294 /* geniCodeDummyRead - generate code for dummy read */
3295 /*-----------------------------------------------------------------*/
3297 geniCodeDummyRead (operand * op)
3300 sym_link *type = operandType (op);
3302 if (!IS_VOLATILE(type))
3305 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3311 /*-----------------------------------------------------------------*/
3312 /* geniCodeSEParms - generate code for side effecting fcalls */
3313 /*-----------------------------------------------------------------*/
3315 geniCodeSEParms (ast * parms,int lvl)
3320 if (parms->type == EX_OP && parms->opval.op == PARAM)
3322 geniCodeSEParms (parms->left,lvl);
3323 geniCodeSEParms (parms->right,lvl);
3327 /* hack don't like this but too lazy to think of
3329 if (IS_ADDRESS_OF_OP (parms))
3330 parms->left->lvalue = 1;
3332 if (IS_CAST_OP (parms) &&
3333 IS_PTR (parms->ftype) &&
3334 IS_ADDRESS_OF_OP (parms->right))
3335 parms->right->left->lvalue = 1;
3337 parms->opval.oprnd =
3338 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3340 parms->type = EX_OPERAND;
3341 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3342 SPEC_ARGREG(parms->ftype);
3345 /*-----------------------------------------------------------------*/
3346 /* geniCodeParms - generates parameters */
3347 /*-----------------------------------------------------------------*/
3349 geniCodeParms (ast * parms, value *argVals, int *stack,
3350 sym_link * ftype, int lvl)
3358 if (argVals==NULL) {
3360 argVals = FUNC_ARGS (ftype);
3363 /* if this is a param node then do the left & right */
3364 if (parms->type == EX_OP && parms->opval.op == PARAM)
3366 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3367 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3371 /* get the parameter value */
3372 if (parms->type == EX_OPERAND)
3373 pval = parms->opval.oprnd;
3376 /* maybe this else should go away ?? */
3377 /* hack don't like this but too lazy to think of
3379 if (IS_ADDRESS_OF_OP (parms))
3380 parms->left->lvalue = 1;
3382 if (IS_CAST_OP (parms) &&
3383 IS_PTR (parms->ftype) &&
3384 IS_ADDRESS_OF_OP (parms->right))
3385 parms->right->left->lvalue = 1;
3387 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3390 /* if register parm then make it a send */
3391 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3392 IFFUNC_ISBUILTIN(ftype))
3394 ic = newiCode (SEND, pval, NULL);
3395 ic->argreg = SPEC_ARGREG(parms->etype);
3396 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3401 /* now decide whether to push or assign */
3402 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3406 operand *top = operandFromSymbol (argVals->sym);
3407 /* clear useDef and other bitVectors */
3408 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3409 geniCodeAssign (top, pval, 1, 0);
3413 sym_link *p = operandType (pval);
3415 ic = newiCode (IPUSH, pval, NULL);
3417 /* update the stack adjustment */
3418 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3423 argVals=argVals->next;
3427 /*-----------------------------------------------------------------*/
3428 /* geniCodeCall - generates temp code for calling */
3429 /*-----------------------------------------------------------------*/
3431 geniCodeCall (operand * left, ast * parms,int lvl)
3435 sym_link *type, *etype;
3439 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3440 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3441 werror (E_FUNCTION_EXPECTED);
3442 return operandFromValue(valueFromLit(0));
3445 /* take care of parameters with side-effecting
3446 function calls in them, this is required to take care
3447 of overlaying function parameters */
3448 geniCodeSEParms (parms,lvl);
3450 ftype = operandType (left);
3451 if (IS_FUNCPTR (ftype))
3452 ftype = ftype->next;
3454 /* first the parameters */
3455 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3457 /* now call : if symbol then pcall */
3458 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3459 ic = newiCode (PCALL, left, NULL);
3461 ic = newiCode (CALL, left, NULL);
3464 type = copyLinkChain (ftype->next);
3465 etype = getSpec (type);
3466 SPEC_EXTR (etype) = 0;
3467 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3471 /* stack adjustment after call */
3472 ic->parmBytes = stack;
3477 /*-----------------------------------------------------------------*/
3478 /* geniCodeReceive - generate intermediate code for "receive" */
3479 /*-----------------------------------------------------------------*/
3481 geniCodeReceive (value * args, operand * func)
3483 unsigned char paramByteCounter = 0;
3485 /* for all arguments that are passed in registers */
3488 if (IS_REGPARM (args->etype))
3490 operand *opr = operandFromValue (args);
3492 symbol *sym = OP_SYMBOL (opr);
3495 /* we will use it after all optimizations
3496 and before liveRange calculation */
3497 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3500 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3501 options.stackAuto == 0 &&
3502 (!(options.model == MODEL_FLAT24)) )
3507 opl = newiTempOperand (args->type, 0);
3509 sym->reqv->key = sym->key;
3510 OP_SYMBOL (sym->reqv)->key = sym->key;
3511 OP_SYMBOL (sym->reqv)->isreqv = 1;
3512 OP_SYMBOL (sym->reqv)->islocal = 0;
3513 SPIL_LOC (sym->reqv) = sym;
3517 ic = newiCode (RECEIVE, func, NULL);
3518 ic->argreg = SPEC_ARGREG(args->etype);
3519 if (ic->argreg == 1) {
3520 currFunc->recvSize = getSize (sym->type);
3522 IC_RESULT (ic) = opr;
3524 /* misuse of parmBytes (normally used for functions)
3525 * to save estimated stack position of this argument.
3526 * Normally this should be zero for RECEIVE iCodes.
3527 * No idea if this causes side effects on other ports. - dw
3529 ic->parmBytes = paramByteCounter;
3531 /* what stack position do we have? */
3532 paramByteCounter += getSize (sym->type);
3541 /*-----------------------------------------------------------------*/
3542 /* geniCodeFunctionBody - create the function body */
3543 /*-----------------------------------------------------------------*/
3545 geniCodeFunctionBody (ast * tree,int lvl)
3552 /* reset the auto generation */
3558 func = ast2iCode (tree->left,lvl+1);
3559 fetype = getSpec (operandType (func));
3561 savelineno = lineno;
3562 lineno = OP_SYMBOL (func)->lineDef;
3563 /* create an entry label */
3564 geniCodeLabel (entryLabel);
3565 lineno = savelineno;
3567 /* create a proc icode */
3568 ic = newiCode (FUNCTION, func, NULL);
3569 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3574 /* for all parameters that are passed
3575 on registers add a "receive" */
3576 geniCodeReceive (tree->values.args, func);
3578 /* generate code for the body */
3579 ast2iCode (tree->right,lvl+1);
3581 /* create a label for return */
3582 geniCodeLabel (returnLabel);
3584 /* now generate the end proc */
3585 ic = newiCode (ENDFUNCTION, func, NULL);
3591 /*-----------------------------------------------------------------*/
3592 /* geniCodeReturn - gen icode for 'return' statement */
3593 /*-----------------------------------------------------------------*/
3595 geniCodeReturn (operand * op)
3599 /* if the operand is present force an rvalue */
3601 op = geniCodeRValue (op, FALSE);
3603 ic = newiCode (RETURN, op, NULL);
3607 /*-----------------------------------------------------------------*/
3608 /* geniCodeIfx - generates code for extended if statement */
3609 /*-----------------------------------------------------------------*/
3611 geniCodeIfx (ast * tree,int lvl)
3614 operand *condition = ast2iCode (tree->left,lvl+1);
3617 /* if condition is null then exit */
3621 condition = geniCodeRValue (condition, FALSE);
3623 cetype = getSpec (operandType (condition));
3624 /* if the condition is a literal */
3625 if (IS_LITERAL (cetype))
3627 if (floatFromVal (condition->operand.valOperand))
3629 if (tree->trueLabel)
3630 geniCodeGoto (tree->trueLabel);
3636 if (tree->falseLabel)
3637 geniCodeGoto (tree->falseLabel);
3644 if (tree->trueLabel)
3646 ic = newiCodeCondition (condition,
3651 if (tree->falseLabel)
3652 geniCodeGoto (tree->falseLabel);
3656 ic = newiCodeCondition (condition,
3663 ast2iCode (tree->right,lvl+1);
3666 /*-----------------------------------------------------------------*/
3667 /* geniCodeJumpTable - tries to create a jump table for switch */
3668 /*-----------------------------------------------------------------*/
3670 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3672 int min, max, cnt = 1;
3679 int needRangeCheck = !optimize.noJTabBoundary
3680 || tree->values.switchVals.swDefault;
3681 sym_link *cetype = getSpec (operandType (cond));
3682 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3683 int sizeofMatchJump, sizeofJumpTable;
3686 if (!tree || !caseVals)
3689 /* the criteria for creating a jump table is */
3690 /* all integer numbers between the maximum & minimum must */
3691 /* be present , the maximum value should not exceed 255 */
3692 /* If not all integer numbers are present the algorithm */
3693 /* inserts jumps to the default label for the missing numbers */
3694 /* and decides later whether it is worth it */
3695 min = (int) floatFromVal (vch = caseVals);
3702 max = (int) floatFromVal (vch);
3704 /* Exit if the range is too large to handle with a jump table. */
3705 if (1 + max - min > port->jumptableCost.maxCount)
3708 switch (getSize (operandType (cond)))
3710 case 1: sizeIndex = 0; break;
3711 case 2: sizeIndex = 1; break;
3712 case 4: sizeIndex = 2; break;
3716 /* Compute the size cost of the range check and subtraction. */
3718 sizeofZeroMinCost = 0;
3722 if (!(min==0 && IS_UNSIGNED (cetype)))
3723 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3724 if (!IS_UNSIGNED (cetype))
3725 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3726 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3729 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3731 /* If the size cost of handling a non-zero minimum exceeds the */
3732 /* cost of extending the range down to zero, then it might be */
3733 /* better to extend the range to zero. */
3734 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3735 >= (min * port->jumptableCost.sizeofElement))
3737 /* Only extend the jump table if it would still be manageable. */
3738 if (1 + max <= port->jumptableCost.maxCount)
3741 if (IS_UNSIGNED (cetype))
3744 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3748 /* Compute the total size cost of a jump table. */
3749 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3750 + port->jumptableCost.sizeofDispatch
3751 + sizeofMinCost + sizeofMaxCost;
3753 /* Compute the total size cost of a match & jump sequence */
3754 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3756 /* If the size cost of the jump table is uneconomical then exit */
3757 if (sizeofMatchJump < sizeofJumpTable)
3760 /* The jump table is preferable. */
3762 /* First, a label for the default or missing cases. */
3763 if (tree->values.switchVals.swDefault)
3765 SNPRINTF (buffer, sizeof(buffer),
3767 tree->values.switchVals.swNum);
3771 SNPRINTF (buffer, sizeof(buffer),
3773 tree->values.switchVals.swNum);
3775 falseLabel = newiTempLabel (buffer);
3777 /* Build the list of labels for the jump table. */
3779 t = (int) floatFromVal (vch);
3780 for (i=min; i<=max; i++)
3784 /* Explicit case: make a new label for it. */
3785 SNPRINTF (buffer, sizeof(buffer),
3787 tree->values.switchVals.swNum,
3789 addSet (&labels, newiTempLabel (buffer));
3792 t = (int) floatFromVal (vch);
3796 /* Implicit case: use the default label. */
3797 addSet (&labels, falseLabel);
3801 /* first we rule out the boundary conditions */
3802 /* if only optimization says so */
3805 sym_link *cetype = getSpec (operandType (cond));
3806 /* no need to check the lower bound if
3807 the condition is unsigned & minimum value is zero */
3808 if (!(min == 0 && IS_UNSIGNED (cetype)))
3810 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3811 ic = newiCodeCondition (boundary, falseLabel, NULL);
3815 /* now for upper bounds */
3816 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3817 ic = newiCodeCondition (boundary, falseLabel, NULL);
3821 /* if the min is not zero then we no make it zero */
3824 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3825 if (!IS_LITERAL(getSpec(operandType(cond))))
3826 setOperandType (cond, UCHARTYPE);
3829 /* now create the jumptable */
3830 ic = newiCode (JUMPTABLE, NULL, NULL);
3831 IC_JTCOND (ic) = cond;
3832 IC_JTLABELS (ic) = labels;
3837 /*-----------------------------------------------------------------*/
3838 /* geniCodeSwitch - changes a switch to a if statement */
3839 /*-----------------------------------------------------------------*/
3841 geniCodeSwitch (ast * tree,int lvl)
3844 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3845 value *caseVals = tree->values.switchVals.swVals;
3846 symbol *trueLabel, *falseLabel;
3848 /* If the condition is a literal, then just jump to the */
3849 /* appropriate case label. */
3850 if (IS_LITERAL(getSpec(operandType(cond))))
3852 int switchVal, caseVal;
3854 switchVal = (int) floatFromVal (cond->operand.valOperand);
3857 caseVal = (int) floatFromVal (caseVals);
3858 if (caseVal == switchVal)
3860 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3861 tree->values.switchVals.swNum, caseVal);
3862 trueLabel = newiTempLabel (buffer);
3863 geniCodeGoto (trueLabel);
3866 caseVals = caseVals->next;
3868 goto defaultOrBreak;
3871 /* If cond is volatile, it might change while we are trying to */
3872 /* find the matching case. To avoid this possibility, make a */
3873 /* non-volatile copy to use instead. */
3874 if (IS_OP_VOLATILE (cond))
3879 newcond = newiTempOperand (operandType (cond), TRUE);
3880 newcond->isvolatile = 0;
3881 ic = newiCode ('=', NULL, cond);
3882 IC_RESULT (ic) = newcond;
3887 /* if we can make this a jump table */
3888 if (geniCodeJumpTable (cond, caseVals, tree))
3889 goto jumpTable; /* no need for the comparison */
3891 /* for the cases defined do */
3895 operand *compare = geniCodeLogic (cond,
3896 operandFromValue (caseVals),
3899 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3900 tree->values.switchVals.swNum,
3901 (int) floatFromVal (caseVals));
3902 trueLabel = newiTempLabel (buffer);
3904 ic = newiCodeCondition (compare, trueLabel, NULL);
3906 caseVals = caseVals->next;
3911 /* if default is present then goto break else break */
3912 if (tree->values.switchVals.swDefault)
3914 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3918 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3921 falseLabel = newiTempLabel (buffer);
3922 geniCodeGoto (falseLabel);
3925 ast2iCode (tree->right,lvl+1);
3928 /*-----------------------------------------------------------------*/
3929 /* geniCodeInline - intermediate code for inline assembler */
3930 /*-----------------------------------------------------------------*/
3932 geniCodeInline (ast * tree)
3936 ic = newiCode (INLINEASM, NULL, NULL);
3937 IC_INLINE (ic) = tree->values.inlineasm;
3941 /*-----------------------------------------------------------------*/
3942 /* geniCodeArrayInit - intermediate code for array initializer */
3943 /*-----------------------------------------------------------------*/
3945 geniCodeArrayInit (ast * tree, operand *array)
3949 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3950 ic = newiCode (ARRAYINIT, array, NULL);
3951 IC_ARRAYILIST (ic) = tree->values.constlist;
3953 operand *left=newOperand(), *right=newOperand();
3954 left->type=right->type=SYMBOL;
3955 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3956 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3957 ic = newiCode (ARRAYINIT, left, right);
3962 /*-----------------------------------------------------------------*/
3963 /* geniCodeCritical - intermediate code for a critical statement */
3964 /*-----------------------------------------------------------------*/
3966 geniCodeCritical (ast *tree, int lvl)
3972 if (!options.stackAuto)
3974 type = newLink(SPECIFIER);
3975 SPEC_VOLATILE(type) = 1;
3976 SPEC_NOUN(type) = V_BIT;
3977 SPEC_SCLS(type) = S_BIT;
3978 SPEC_BLEN(type) = 1;
3979 SPEC_BSTR(type) = 0;
3980 op = newiTempOperand(type, 1);
3983 /* If op is NULL, the original interrupt state will saved on */
3984 /* the stack. Otherwise, it will be saved in op. */
3986 /* Generate a save of the current interrupt state & disable */
3987 ic = newiCode (CRITICAL, NULL, NULL);
3988 IC_RESULT (ic) = op;
3991 /* Generate the critical code sequence */
3992 if (tree->left && tree->left->type == EX_VALUE)
3993 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3995 ast2iCode (tree->left,lvl+1);
3997 /* Generate a restore of the original interrupt state */
3998 ic = newiCode (ENDCRITICAL, NULL, op);
4002 /*-----------------------------------------------------------------*/
4003 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
4004 /* particular case. Ie : assigning or dereferencing array or ptr */
4005 /*-----------------------------------------------------------------*/
4006 set * lvaluereqSet = NULL;
4007 typedef struct lvalItem
4014 /*-----------------------------------------------------------------*/
4015 /* addLvaluereq - add a flag for lvalreq for current ast level */
4016 /*-----------------------------------------------------------------*/
4017 void addLvaluereq(int lvl)
4019 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4022 addSetHead(&lvaluereqSet,lpItem);
4025 /*-----------------------------------------------------------------*/
4026 /* delLvaluereq - del a flag for lvalreq for current ast level */
4027 /*-----------------------------------------------------------------*/
4031 lpItem = getSet(&lvaluereqSet);
4032 if(lpItem) Safe_free(lpItem);
4034 /*-----------------------------------------------------------------*/
4035 /* clearLvaluereq - clear lvalreq flag */
4036 /*-----------------------------------------------------------------*/
4037 void clearLvaluereq()
4040 lpItem = peekSet(lvaluereqSet);
4041 if(lpItem) lpItem->req = 0;
4043 /*-----------------------------------------------------------------*/
4044 /* getLvaluereq - get the last lvalreq level */
4045 /*-----------------------------------------------------------------*/
4046 int getLvaluereqLvl()
4049 lpItem = peekSet(lvaluereqSet);
4050 if(lpItem) return lpItem->lvl;
4053 /*-----------------------------------------------------------------*/
4054 /* isLvaluereq - is lvalreq valid for this level ? */
4055 /*-----------------------------------------------------------------*/
4056 int isLvaluereq(int lvl)
4059 lpItem = peekSet(lvaluereqSet);
4060 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4064 /*-----------------------------------------------------------------*/
4065 /* ast2iCode - creates an icodeList from an ast */
4066 /*-----------------------------------------------------------------*/
4068 ast2iCode (ast * tree,int lvl)
4070 operand *left = NULL;
4071 operand *right = NULL;
4075 /* set the global variables for filename & line number */
4077 filename = tree->filename;
4079 lineno = tree->lineno;
4081 block = tree->block;
4083 scopeLevel = tree->level;
4085 seqPoint = tree->seqPoint;
4087 if (tree->type == EX_VALUE)
4088 return operandFromValue (tree->opval.val);
4090 if (tree->type == EX_LINK)
4091 return operandFromLink (tree->opval.lnk);
4093 /* if we find a nullop */
4094 if (tree->type == EX_OP &&
4095 (tree->opval.op == NULLOP ||
4096 tree->opval.op == BLOCK))
4098 if (tree->left && tree->left->type == EX_VALUE)
4099 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4101 ast2iCode (tree->left,lvl+1);
4102 if (tree->right && tree->right->type == EX_VALUE)
4103 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4105 ast2iCode (tree->right,lvl+1);
4109 /* special cases for not evaluating */
4110 if (tree->opval.op != ':' &&
4111 tree->opval.op != '?' &&
4112 tree->opval.op != CALL &&
4113 tree->opval.op != IFX &&
4114 tree->opval.op != AND_OP &&
4115 tree->opval.op != OR_OP &&
4116 tree->opval.op != LABEL &&
4117 tree->opval.op != GOTO &&
4118 tree->opval.op != SWITCH &&
4119 tree->opval.op != FUNCTION &&
4120 tree->opval.op != INLINEASM &&
4121 tree->opval.op != CRITICAL)
4124 if (IS_ASSIGN_OP (tree->opval.op) ||
4125 IS_DEREF_OP (tree) ||
4126 (tree->opval.op == '&' && !tree->right) ||
4127 tree->opval.op == PTR_OP)
4130 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4131 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4134 left = operandFromAst (tree->left,lvl);
4136 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4137 left = geniCodeRValue (left, TRUE);
4141 left = operandFromAst (tree->left,lvl);
4143 if (tree->opval.op == INC_OP ||
4144 tree->opval.op == DEC_OP)
4147 right = operandFromAst (tree->right,lvl);
4152 right = operandFromAst (tree->right,lvl);
4156 /* now depending on the type of operand */
4157 /* this will be a biggy */
4158 switch (tree->opval.op)
4161 case '[': /* array operation */
4163 //sym_link *ltype = operandType (left);
4164 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4165 left = geniCodeRValue (left, FALSE);
4166 right = geniCodeRValue (right, TRUE);
4169 return geniCodeArray (left, right,lvl);
4171 case '.': /* structure dereference */
4172 if (IS_PTR (operandType (left)))
4173 left = geniCodeRValue (left, TRUE);
4175 left = geniCodeRValue (left, FALSE);
4177 return geniCodeStruct (left, right, tree->lvalue);
4179 case PTR_OP: /* structure pointer dereference */
4182 pType = operandType (left);
4183 left = geniCodeRValue (left, TRUE);
4185 setOClass (pType, getSpec (operandType (left)));
4188 return geniCodeStruct (left, right, tree->lvalue);
4190 case INC_OP: /* increment operator */
4192 return geniCodePostInc (left);
4194 return geniCodePreInc (right, tree->lvalue);
4196 case DEC_OP: /* decrement operator */
4198 return geniCodePostDec (left);
4200 return geniCodePreDec (right, tree->lvalue);
4202 case '&': /* bitwise and or address of operator */
4204 { /* this is a bitwise operator */
4205 left = geniCodeRValue (left, FALSE);
4206 right = geniCodeRValue (right, FALSE);
4207 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4210 return geniCodeAddressOf (left);
4212 case '|': /* bitwise or & xor */
4214 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4215 geniCodeRValue (right, FALSE),
4220 return geniCodeDivision (geniCodeRValue (left, FALSE),
4221 geniCodeRValue (right, FALSE),
4222 getResultTypeFromType (tree->ftype));
4225 return geniCodeModulus (geniCodeRValue (left, FALSE),
4226 geniCodeRValue (right, FALSE),
4227 getResultTypeFromType (tree->ftype));
4230 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4231 geniCodeRValue (right, FALSE),
4232 getResultTypeFromType (tree->ftype));
4234 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4238 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4239 geniCodeRValue (right, FALSE),
4240 getResultTypeFromType (tree->ftype));
4242 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4246 return geniCodeAdd (geniCodeRValue (left, FALSE),
4247 geniCodeRValue (right, FALSE),
4248 getResultTypeFromType (tree->ftype),
4251 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4254 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4255 geniCodeRValue (right, FALSE),
4256 getResultTypeFromType (tree->ftype));
4259 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4260 geniCodeRValue (right, FALSE));
4262 #if 0 // this indeed needs a second thought
4266 // let's keep this simple: get the rvalue we need
4267 op=geniCodeRValue (right, FALSE);
4268 // now cast it to whatever we want
4269 op=geniCodeCast (operandType(left), op, FALSE);
4270 // if this is going to be used as an lvalue, make it so
4276 #else // bug #604575, is it a bug ????
4277 return geniCodeCast (operandType (left),
4278 geniCodeRValue (right, FALSE), FALSE);
4285 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4290 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4291 setOperandType (op, UCHARTYPE);
4298 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4299 geniCodeRValue (right, FALSE),
4301 setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4306 return geniCodeLogicAndOr (tree, lvl);
4313 /* different compilers (even different gccs) evaluate
4314 the two calls in a different order. to get the same
4315 result on all machines we've to specify a clear sequence.
4316 return geniCodeLogic (geniCodeRValue (left, FALSE),
4317 geniCodeRValue (right, FALSE),
4321 operand *leftOp, *rightOp;
4323 leftOp = geniCodeRValue (left , FALSE);
4324 rightOp = geniCodeRValue (right, FALSE);
4326 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4329 return geniCodeConditional (tree,lvl);
4332 return operandFromLit (getSize (tree->right->ftype));
4336 sym_link *rtype = operandType (right);
4337 sym_link *ltype = operandType (left);
4338 if (IS_PTR (rtype) && IS_ITEMP (right)
4339 && right->isaddr && compareType (rtype->next, ltype) == 1)
4340 right = geniCodeRValue (right, TRUE);
4342 right = geniCodeRValue (right, FALSE);
4344 geniCodeAssign (left, right, 0, 1);
4349 geniCodeAssign (left,
4350 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4352 geniCodeRValue (right, FALSE),
4353 getResultTypeFromType (tree->ftype)),
4358 geniCodeAssign (left,
4359 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4361 geniCodeRValue (right, FALSE),
4362 getResultTypeFromType (tree->ftype)),
4366 geniCodeAssign (left,
4367 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4369 geniCodeRValue (right, FALSE),
4370 getResultTypeFromType (tree->ftype)),
4374 sym_link *rtype = operandType (right);
4375 sym_link *ltype = operandType (left);
4376 if (IS_PTR (rtype) && IS_ITEMP (right)
4377 && right->isaddr && compareType (rtype->next, ltype) == 1)
4378 right = geniCodeRValue (right, TRUE);
4380 right = geniCodeRValue (right, FALSE);
4383 return geniCodeAssign (left,
4384 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4387 getResultTypeFromType (tree->ftype),
4393 sym_link *rtype = operandType (right);
4394 sym_link *ltype = operandType (left);
4395 if (IS_PTR (rtype) && IS_ITEMP (right)
4396 && right->isaddr && compareType (rtype->next, ltype) == 1)
4398 right = geniCodeRValue (right, TRUE);
4402 right = geniCodeRValue (right, FALSE);
4405 geniCodeAssign (left,
4406 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4409 getResultTypeFromType (tree->ftype)),
4414 geniCodeAssign (left,
4415 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4417 geniCodeRValue (right, FALSE),
4418 getResultTypeFromType (tree->ftype)),
4422 geniCodeAssign (left,
4423 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4425 geniCodeRValue (right, FALSE)), 0, 1);
4428 geniCodeAssign (left,
4429 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4431 geniCodeRValue (right, FALSE),
4433 operandType (left)), 0, 1);
4436 geniCodeAssign (left,
4437 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4439 geniCodeRValue (right, FALSE),
4441 operandType (left)), 0, 1);
4444 geniCodeAssign (left,
4445 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4447 geniCodeRValue (right, FALSE),
4449 operandType (left)), 0, 1);
4451 return geniCodeRValue (right, FALSE);
4454 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4457 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4458 return ast2iCode (tree->right,lvl+1);
4461 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4462 return ast2iCode (tree->right,lvl+1);
4465 geniCodeFunctionBody (tree,lvl);
4469 geniCodeReturn (right);
4473 geniCodeIfx (tree,lvl);
4477 geniCodeSwitch (tree,lvl);
4481 geniCodeInline (tree);
4485 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4489 geniCodeCritical (tree, lvl);
4495 /*-----------------------------------------------------------------*/
4496 /* reverseICChain - gets from the list and creates a linkedlist */
4497 /*-----------------------------------------------------------------*/
4504 while ((loop = getSet (&iCodeChain)))
4516 /*-----------------------------------------------------------------*/
4517 /* iCodeFromAst - given an ast will convert it to iCode */
4518 /*-----------------------------------------------------------------*/
4520 iCodeFromAst (ast * tree)
4522 returnLabel = newiTempLabel ("_return");
4523 entryLabel = newiTempLabel ("_entry");
4525 return reverseiCChain ();
4528 static const char *opTypeToStr(OPTYPE op)
4532 case SYMBOL: return "symbol";
4533 case VALUE: return "value";
4534 case TYPE: return "type";
4536 return "undefined type";
4540 operand *validateOpType(operand *op,
4547 if (op && op->type == type)
4552 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4553 " expected %s, got %s\n",
4554 macro, args, file, line,
4555 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4557 return op; // never reached, makes compiler happy.