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 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) ||
1333 retval = operandFromLit (operandLitValue (left) ==
1334 operandLitValue (right));
1337 if (IS_FIXED16X16 (let) ||
1338 IS_FIXED16X16 (ret))
1340 retval = operandFromLit (operandLitValue (left) ==
1341 operandLitValue (right));
1345 /* this op doesn't care about signedness */
1348 l = (TYPE_UDWORD) operandLitValue (left);
1349 r = (TYPE_UDWORD) operandLitValue (right);
1350 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1351 neccessary to strip them to 16 bit.
1352 Literals are reduced to their cheapest type, therefore left and
1353 right might have different types. It's neccessary to find a
1354 common type: int (used for char too) or long */
1355 if (!IS_LONG (let) &&
1361 retval = operandFromLit (l == r);
1365 retval = operandFromLit (operandLitValue (left) <
1366 operandLitValue (right));
1369 retval = operandFromLit (operandLitValue (left) <=
1370 operandLitValue (right));
1373 retval = operandFromLit (operandLitValue (left) !=
1374 operandLitValue (right));
1377 retval = operandFromLit (operandLitValue (left) >
1378 operandLitValue (right));
1381 retval = operandFromLit (operandLitValue (left) >=
1382 operandLitValue (right));
1385 retval = operandFromValue (valCastLiteral (type,
1386 (TYPE_UDWORD)operandLitValue(left) &
1387 (TYPE_UDWORD)operandLitValue(right)));
1390 retval = operandFromValue (valCastLiteral (type,
1391 (TYPE_UDWORD)operandLitValue(left) |
1392 (TYPE_UDWORD)operandLitValue(right)));
1395 retval = operandFromValue (valCastLiteral (type,
1396 (TYPE_UDWORD)operandLitValue(left) ^
1397 (TYPE_UDWORD)operandLitValue(right)));
1400 retval = operandFromLit (operandLitValue (left) &&
1401 operandLitValue (right));
1404 retval = operandFromLit (operandLitValue (left) ||
1405 operandLitValue (right));
1409 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1411 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1417 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1419 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1424 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1425 (TYPE_UDWORD)operandLitValue(right)) & 1);
1428 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1429 (TYPE_UDWORD)operandLitValue(right)) & 0xFF);
1432 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1433 (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF);
1437 retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
1438 ((getSize (let) * 8) - 1)) & 1);
1442 retval = operandFromValue (valCastLiteral (type,
1443 -1 * operandLitValue (left)));
1447 retval = operandFromValue (valCastLiteral (type,
1449 operandLitValue (left))));
1453 retval = operandFromLit (!operandLitValue (left));
1457 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1458 " operandOperation invalid operator ");
1466 /*-----------------------------------------------------------------*/
1467 /* isOperandEqual - compares two operand & return 1 if they r = */
1468 /*-----------------------------------------------------------------*/
1470 isOperandEqual (operand * left, operand * right)
1472 /* if the pointers are equal then they are equal */
1476 /* if either of them null then false */
1477 if (!left || !right)
1480 if (left->type != right->type)
1483 if (IS_SYMOP (left) && IS_SYMOP (right))
1484 return left->key == right->key;
1486 /* if types are the same */
1490 return isSymbolEqual (left->operand.symOperand,
1491 right->operand.symOperand);
1493 return (compareType (left->operand.valOperand->type,
1494 right->operand.valOperand->type) &&
1495 (floatFromVal (left->operand.valOperand) ==
1496 floatFromVal (right->operand.valOperand)));
1498 if (compareType (left->operand.typeOperand,
1499 right->operand.typeOperand) == 1)
1506 /*-------------------------------------------------------------------*/
1507 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1508 /*-------------------------------------------------------------------*/
1510 isiCodeEqual (iCode * left, iCode * right)
1512 /* if the same pointer */
1516 /* if either of them null */
1517 if (!left || !right)
1520 /* if operand are the same */
1521 if (left->op == right->op)
1524 /* compare all the elements depending on type */
1525 if (left->op != IFX)
1527 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1529 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1535 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1537 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1539 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1548 /*-----------------------------------------------------------------*/
1549 /* newiTempFromOp - create a temp Operand with same attributes */
1550 /*-----------------------------------------------------------------*/
1552 newiTempFromOp (operand * op)
1562 nop = newiTempOperand (operandType (op), TRUE);
1563 nop->isaddr = op->isaddr;
1564 nop->isvolatile = op->isvolatile;
1565 nop->isGlobal = op->isGlobal;
1566 nop->isLiteral = op->isLiteral;
1567 nop->usesDefs = op->usesDefs;
1568 nop->isParm = op->isParm;
1572 /*-----------------------------------------------------------------*/
1573 /* operand from operand - creates an operand holder for the type */
1574 /*-----------------------------------------------------------------*/
1576 operandFromOperand (operand * op)
1582 nop = newOperand ();
1583 nop->type = op->type;
1584 nop->isaddr = op->isaddr;
1586 nop->isvolatile = op->isvolatile;
1587 nop->isGlobal = op->isGlobal;
1588 nop->isLiteral = op->isLiteral;
1589 nop->usesDefs = op->usesDefs;
1590 nop->isParm = op->isParm;
1595 nop->operand.symOperand = op->operand.symOperand;
1598 nop->operand.valOperand = op->operand.valOperand;
1601 nop->operand.typeOperand = op->operand.typeOperand;
1608 /*-----------------------------------------------------------------*/
1609 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1610 /*-----------------------------------------------------------------*/
1612 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1614 operand *nop = operandFromOperand (op);
1616 if (nop->type == SYMBOL)
1618 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1619 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1625 /*-----------------------------------------------------------------*/
1626 /* operandFromSymbol - creates an operand from a symbol */
1627 /*-----------------------------------------------------------------*/
1629 operandFromSymbol (symbol * sym)
1634 /* if the symbol's type is a literal */
1635 /* then it is an enumerator type */
1636 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1637 return operandFromValue (valFromType (sym->etype));
1640 sym->key = ++operandKey;
1642 /* if this an implicit variable, means struct/union */
1643 /* member so just return it */
1644 if (sym->implicit || IS_FUNC (sym->type))
1648 op->operand.symOperand = sym;
1650 op->isvolatile = isOperandVolatile (op, TRUE);
1651 op->isGlobal = isOperandGlobal (op);
1655 /* under the following conditions create a
1656 register equivalent for a local symbol */
1657 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1658 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1660 (!(options.model == MODEL_FLAT24)) ) &&
1661 options.stackAuto == 0)
1664 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1665 !IS_FUNC (sym->type) && /* not a function */
1666 !sym->_isparm && /* not a parameter */
1667 IS_AUTO (sym) && /* is a local auto variable */
1668 !sym->addrtaken && /* whose address has not been taken */
1669 !sym->reqv && /* does not already have a reg equivalence */
1670 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1671 !sym->islbl && /* not a label */
1672 ok /* farspace check */
1676 /* we will use it after all optimizations
1677 and before liveRange calculation */
1678 sym->reqv = newiTempOperand (sym->type, 0);
1679 sym->reqv->key = sym->key;
1680 OP_SYMBOL (sym->reqv)->prereqv = sym;
1681 OP_SYMBOL (sym->reqv)->key = sym->key;
1682 OP_SYMBOL (sym->reqv)->isreqv = 1;
1683 OP_SYMBOL (sym->reqv)->islocal = 1;
1684 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1685 SPIL_LOC (sym->reqv) = sym;
1688 if (!IS_AGGREGATE (sym->type))
1692 op->operand.symOperand = sym;
1695 op->isvolatile = isOperandVolatile (op, TRUE);
1696 op->isGlobal = isOperandGlobal (op);
1697 op->isPtr = IS_PTR (operandType (op));
1698 op->isParm = sym->_isparm;
1703 /* itemp = &[_symbol] */
1705 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1706 IC_LEFT (ic)->type = SYMBOL;
1707 IC_LEFT (ic)->operand.symOperand = sym;
1708 IC_LEFT (ic)->key = sym->key;
1709 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1710 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1711 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1714 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1715 if (IS_ARRAY (sym->type))
1717 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1718 IC_RESULT (ic)->isaddr = 0;
1721 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1725 return IC_RESULT (ic);
1728 /*-----------------------------------------------------------------*/
1729 /* operandFromValue - creates an operand from value */
1730 /*-----------------------------------------------------------------*/
1732 operandFromValue (value * val)
1736 /* if this is a symbol then do the symbol thing */
1738 return operandFromSymbol (val->sym);
1740 /* this is not a symbol */
1743 op->operand.valOperand = val;
1744 op->isLiteral = isOperandLiteral (op);
1748 /*-----------------------------------------------------------------*/
1749 /* operandFromLink - operand from typeChain */
1750 /*-----------------------------------------------------------------*/
1752 operandFromLink (sym_link * type)
1756 /* operand from sym_link */
1762 op->operand.typeOperand = copyLinkChain (type);
1766 /*-----------------------------------------------------------------*/
1767 /* operandFromLit - makes an operand from a literal value */
1768 /*-----------------------------------------------------------------*/
1770 operandFromLit (double i)
1772 return operandFromValue (valueFromLit (i));
1775 /*-----------------------------------------------------------------*/
1776 /* operandFromAst - creates an operand from an ast */
1777 /*-----------------------------------------------------------------*/
1779 operandFromAst (ast * tree,int lvl)
1785 /* depending on type do */
1789 return ast2iCode (tree,lvl+1);
1793 return operandFromValue (tree->opval.val);
1797 return operandFromLink (tree->opval.lnk);
1804 /* Just to keep the compiler happy */
1805 return (operand *) 0;
1808 /*-----------------------------------------------------------------*/
1809 /* setOperandType - sets the operand's type to the given type */
1810 /*-----------------------------------------------------------------*/
1812 setOperandType (operand * op, sym_link * type)
1814 /* depending on the type of operand */
1819 op->operand.valOperand->etype =
1820 getSpec (op->operand.valOperand->type =
1821 copyLinkChain (type));
1825 if (op->operand.symOperand->isitmp)
1826 op->operand.symOperand->etype =
1827 getSpec (op->operand.symOperand->type =
1828 copyLinkChain (type));
1830 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1831 "attempt to modify type of source");
1835 op->operand.typeOperand = copyLinkChain (type);
1841 /*-----------------------------------------------------------------*/
1842 /* Get size in byte of ptr need to access an array */
1843 /*-----------------------------------------------------------------*/
1845 getArraySizePtr (operand * op)
1847 sym_link *ltype = operandType(op);
1851 int size = getSize(ltype);
1852 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1857 sym_link *letype = getSpec(ltype);
1858 switch (PTR_TYPE (SPEC_OCLS (letype)))
1870 if (GPTRSIZE > FPTRSIZE)
1871 return (GPTRSIZE-1);
1882 /*-----------------------------------------------------------------*/
1883 /* perform "usual unary conversions" */
1884 /*-----------------------------------------------------------------*/
1887 usualUnaryConversions (operand * op)
1889 if (IS_INTEGRAL (operandType (op)))
1891 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1894 return geniCodeCast (INTTYPE, op, TRUE);
1901 /*-----------------------------------------------------------------*/
1902 /* perform "usual binary conversions" */
1903 /*-----------------------------------------------------------------*/
1906 usualBinaryConversions (operand ** op1, operand ** op2,
1907 RESULT_TYPE resultType, int op)
1910 sym_link *rtype = operandType (*op2);
1911 sym_link *ltype = operandType (*op1);
1913 ctype = computeType (ltype, rtype, resultType, op);
1920 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1922 /* one byte operations: keep signedness for code generator */
1930 *op1 = geniCodeCast (ctype, *op1, TRUE);
1931 *op2 = geniCodeCast (ctype, *op2, TRUE);
1936 /*-----------------------------------------------------------------*/
1937 /* geniCodeValueAtAddress - generate intermeditate code for value */
1939 /*-----------------------------------------------------------------*/
1941 geniCodeRValue (operand * op, bool force)
1944 sym_link *type = operandType (op);
1945 sym_link *etype = getSpec (type);
1947 /* if this is an array & already */
1948 /* an address then return this */
1949 if (IS_AGGREGATE (type) ||
1950 (IS_PTR (type) && !force && !op->isaddr))
1951 return operandFromOperand (op);
1953 /* if this is not an address then must be */
1954 /* rvalue already so return this one */
1958 /* if this is not a temp symbol then */
1959 if (!IS_ITEMP (op) &&
1961 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1963 op = operandFromOperand (op);
1968 if (IS_SPEC (type) &&
1969 IS_TRUE_SYMOP (op) &&
1970 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1971 (options.model == MODEL_FLAT24) ))
1973 op = operandFromOperand (op);
1978 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1979 if (IS_PTR (type) && op->isaddr && force)
1982 type = copyLinkChain (type);
1984 IC_RESULT (ic) = newiTempOperand (type, 1);
1985 IC_RESULT (ic)->isaddr = 0;
1987 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1991 return IC_RESULT (ic);
1994 /*-----------------------------------------------------------------*/
1995 /* geniCodeCast - changes the value from one type to another */
1996 /*-----------------------------------------------------------------*/
1998 geniCodeCast (sym_link * type, operand * op, bool implicit)
2002 sym_link *opetype = getSpec (optype = operandType (op));
2006 /* one of them has size zero then error */
2007 if (IS_VOID (optype))
2009 werror (E_CAST_ZERO);
2013 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
2015 geniCodeArray2Ptr (op);
2019 /* if the operand is already the desired type then do nothing */
2020 if (compareType (type, optype) == 1)
2023 /* if this is a literal then just change the type & return */
2024 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
2026 return operandFromValue (valCastLiteral (type,
2027 operandLitValue (op)));
2030 /* if casting to/from pointers, do some checking */
2031 if (IS_PTR(type)) { // to a pointer
2032 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
2033 if (IS_INTEGRAL(optype)) {
2034 // maybe this is NULL, than it's ok.
2035 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
2036 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
2037 // no way to set the storage
2038 if (IS_LITERAL(optype)) {
2039 werror(E_LITERAL_GENERIC);
2042 werror(E_NONPTR2_GENPTR);
2045 } else if (implicit) {
2046 werror(W_INTEGRAL2PTR_NOCAST);
2051 // shouldn't do that with float, array or structure unless to void
2052 if (!IS_VOID(getSpec(type)) &&
2053 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2054 werror(E_INCOMPAT_TYPES);
2058 } else { // from a pointer to a pointer
2059 if (IS_GENPTR(type) && IS_VOID(type->next))
2060 { // cast to void* is always allowed
2062 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2063 { // cast from void* is always allowed
2065 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2066 // if not a pointer to a function
2067 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2068 if (implicit) { // if not to generic, they have to match
2069 if (!IS_GENPTR(type) &&
2070 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2071 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2075 werror(E_INCOMPAT_PTYPES);
2082 } else { // to a non pointer
2083 if (IS_PTR(optype)) { // from a pointer
2084 if (implicit) { // sneaky
2085 if (IS_INTEGRAL(type)) {
2086 werror(W_PTR2INTEGRAL_NOCAST);
2088 } else { // shouldn't do that with float, array or structure
2089 werror(E_INCOMPAT_TYPES);
2096 printFromToType (optype, type);
2099 /* if they are the same size create an assignment */
2101 /* This seems very dangerous to me, since there are several */
2102 /* optimizations (for example, gcse) that don't notice the */
2103 /* cast hidden in this assignement and may simplify an */
2104 /* iCode to use the original (uncasted) operand. */
2105 /* Unfortunately, other things break when this cast is */
2106 /* made explicit. Need to fix this someday. */
2107 /* -- EEP, 2004/01/21 */
2108 if (getSize (type) == getSize (optype) &&
2109 !IS_BITFIELD (type) &&
2111 !IS_FLOAT (optype) &&
2113 !IS_FIXED (optype) &&
2114 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2115 (!IS_SPEC (type) && !IS_SPEC (optype))))
2117 ic = newiCode ('=', NULL, op);
2118 IC_RESULT (ic) = newiTempOperand (type, 0);
2119 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2120 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2121 IC_RESULT (ic)->isaddr = 0;
2125 ic = newiCode (CAST, operandFromLink (type),
2126 geniCodeRValue (op, FALSE));
2128 IC_RESULT (ic) = newiTempOperand (type, 0);
2131 /* preserve the storage class & output class */
2132 /* of the original variable */
2133 restype = getSpec (operandType (IC_RESULT (ic)));
2134 if (!IS_LITERAL(opetype) &&
2137 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2138 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2141 return IC_RESULT (ic);
2144 /*-----------------------------------------------------------------*/
2145 /* geniCodeLabel - will create a Label */
2146 /*-----------------------------------------------------------------*/
2148 geniCodeLabel (symbol * label)
2152 ic = newiCodeLabelGoto (LABEL, label);
2156 /*-----------------------------------------------------------------*/
2157 /* geniCodeGoto - will create a Goto */
2158 /*-----------------------------------------------------------------*/
2160 geniCodeGoto (symbol * label)
2164 ic = newiCodeLabelGoto (GOTO, label);
2168 /*-----------------------------------------------------------------*/
2169 /* geniCodeMultiply - gen intermediate code for multiplication */
2170 /*-----------------------------------------------------------------*/
2172 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2179 /* if they are both literal then we know the result */
2180 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2181 return operandFromValue (valMult (left->operand.valOperand,
2182 right->operand.valOperand));
2184 if (IS_LITERAL(retype)) {
2185 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2188 resType = usualBinaryConversions (&left, &right, resultType, '*');
2190 rtype = operandType (right);
2191 retype = getSpec (rtype);
2192 ltype = operandType (left);
2193 letype = getSpec (ltype);
2196 /* if the right is a literal & power of 2 */
2197 /* then make it a left shift */
2198 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2199 efficient in most cases than 2 bytes result = 2 bytes << literal
2200 if port has 1 byte muldiv */
2201 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2202 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2203 && (port->support.muldiv == 1))
2204 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2205 && strcmp (port->target, "pic14") != 0)
2207 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2209 /* LEFT_OP need same size for left and result, */
2210 left = geniCodeCast (resType, left, TRUE);
2211 ltype = operandType (left);
2213 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2217 ic = newiCode ('*', left, right); /* normal multiplication */
2218 /* if the size left or right > 1 then support routine */
2219 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2223 IC_RESULT (ic) = newiTempOperand (resType, 1);
2226 return IC_RESULT (ic);
2229 /*-----------------------------------------------------------------*/
2230 /* geniCodeDivision - gen intermediate code for division */
2231 /*-----------------------------------------------------------------*/
2233 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2238 sym_link *rtype = operandType (right);
2239 sym_link *retype = getSpec (rtype);
2240 sym_link *ltype = operandType (left);
2241 sym_link *letype = getSpec (ltype);
2243 resType = usualBinaryConversions (&left, &right, resultType, '/');
2245 /* if the right is a literal & power of 2
2246 and left is unsigned then make it a
2248 if (IS_LITERAL (retype) &&
2249 !IS_FLOAT (letype) &&
2250 !IS_FIXED (letype) &&
2251 IS_UNSIGNED(letype) &&
2252 ((p2 = powof2 ((TYPE_UDWORD)
2253 floatFromVal (right->operand.valOperand))) > 0)) {
2254 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2258 ic = newiCode ('/', left, right); /* normal division */
2259 /* if the size left or right > 1 then support routine */
2260 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2263 IC_RESULT (ic) = newiTempOperand (resType, 0);
2266 return IC_RESULT (ic);
2268 /*-----------------------------------------------------------------*/
2269 /* geniCodeModulus - gen intermediate code for modulus */
2270 /*-----------------------------------------------------------------*/
2272 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2278 /* if they are both literal then we know the result */
2279 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2280 return operandFromValue (valMod (left->operand.valOperand,
2281 right->operand.valOperand));
2283 resType = usualBinaryConversions (&left, &right, resultType, '%');
2285 /* now they are the same size */
2286 ic = newiCode ('%', left, right);
2288 /* if the size left or right > 1 then support routine */
2289 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2291 IC_RESULT (ic) = newiTempOperand (resType, 0);
2294 return IC_RESULT (ic);
2297 /*-----------------------------------------------------------------*/
2298 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2299 /*-----------------------------------------------------------------*/
2301 geniCodePtrPtrSubtract (operand * left, operand * right)
2307 /* if they are both literals then */
2308 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2310 result = operandFromValue (valMinus (left->operand.valOperand,
2311 right->operand.valOperand));
2315 ic = newiCode ('-', left, right);
2317 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2321 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2325 // should we really do this? is this ANSI?
2326 return geniCodeDivision (result,
2327 operandFromLit (getSize (ltype->next)),
2331 /*-----------------------------------------------------------------*/
2332 /* geniCodeSubtract - generates code for subtraction */
2333 /*-----------------------------------------------------------------*/
2335 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2342 /* if they both pointers then */
2343 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2344 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2345 return geniCodePtrPtrSubtract (left, right);
2347 /* if they are both literal then we know the result */
2348 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2349 && left->isLiteral && right->isLiteral)
2350 return operandFromValue (valMinus (left->operand.valOperand,
2351 right->operand.valOperand));
2353 /* if left is an array or pointer */
2354 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2356 isarray = left->isaddr;
2357 right = geniCodeMultiply (right,
2358 operandFromLit (getSize (ltype->next)),
2359 (getArraySizePtr(left) >= INTSIZE) ?
2362 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2365 { /* make them the same size */
2366 resType = usualBinaryConversions (&left, &right, resultType, '-');
2369 ic = newiCode ('-', left, right);
2371 IC_RESULT (ic) = newiTempOperand (resType, 1);
2372 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2374 /* if left or right is a float */
2375 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2376 || IS_FIXED (ltype) || IS_FIXED (rtype))
2380 return IC_RESULT (ic);
2383 /*-----------------------------------------------------------------*/
2384 /* geniCodeAdd - generates iCode for addition */
2385 /*-----------------------------------------------------------------*/
2387 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2396 /* if the right side is LITERAL zero */
2397 /* return the left side */
2398 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2401 /* if left is literal zero return right */
2402 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2405 /* if left is a pointer then size */
2406 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2408 isarray = left->isaddr;
2409 // there is no need to multiply with 1
2410 if (getSize (ltype->next) != 1)
2412 size = operandFromLit (getSize (ltype->next));
2413 SPEC_USIGN (getSpec (operandType (size))) = 1;
2414 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2415 right = geniCodeMultiply (right,
2417 (getArraySizePtr(left) >= INTSIZE) ?
2420 /* Even if right is a 'unsigned char',
2421 the result will be a 'signed int' due to the promotion rules.
2422 It doesn't make sense when accessing arrays, so let's fix it here: */
2424 SPEC_USIGN (getSpec (operandType (right))) = 1;
2426 resType = copyLinkChain (ltype);
2429 { // make them the same size
2430 resType = usualBinaryConversions (&left, &right, resultType, '+');
2433 /* if they are both literals then we know */
2434 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2435 && left->isLiteral && right->isLiteral)
2436 return operandFromValue (valPlus (valFromType (ltype),
2437 valFromType (rtype)));
2439 ic = newiCode ('+', left, right);
2441 IC_RESULT (ic) = newiTempOperand (resType, 1);
2442 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2444 /* if left or right is a float then support
2446 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2447 || IS_FIXED (ltype) || IS_FIXED (rtype))
2452 return IC_RESULT (ic);
2456 /*-----------------------------------------------------------------*/
2457 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2458 /*-----------------------------------------------------------------*/
2460 aggrToPtr (sym_link * type, bool force)
2465 if (IS_PTR (type) && !force)
2468 etype = getSpec (type);
2469 ptype = newLink (DECLARATOR);
2473 /* set the pointer depending on the storage class */
2474 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2478 /*------------------------------------------------------------------*/
2479 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2480 /*------------------------------------------------------------------*/
2482 aggrToPtrDclType (sym_link * type, bool force)
2484 if (IS_PTR (type) && !force)
2485 return DCL_TYPE (type);
2487 /* return the pointer depending on the storage class */
2488 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2491 /*-----------------------------------------------------------------*/
2492 /* geniCodeArray2Ptr - array to pointer */
2493 /*-----------------------------------------------------------------*/
2495 geniCodeArray2Ptr (operand * op)
2497 sym_link *optype = operandType (op);
2498 sym_link *opetype = getSpec (optype);
2500 /* set the pointer depending on the storage class */
2501 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2508 /*-----------------------------------------------------------------*/
2509 /* geniCodeArray - array access */
2510 /*-----------------------------------------------------------------*/
2512 geniCodeArray (operand * left, operand * right, int lvl)
2516 sym_link *ltype = operandType (left);
2521 if (IS_PTR (ltype->next) && left->isaddr)
2523 left = geniCodeRValue (left, FALSE);
2526 return geniCodeDerefPtr (geniCodeAdd (left,
2528 (getArraySizePtr(left) >= INTSIZE) ?
2534 size = operandFromLit (getSize (ltype->next));
2535 SPEC_USIGN (getSpec (operandType (size))) = 1;
2536 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2537 right = geniCodeMultiply (right,
2539 (getArraySizePtr(left) >= INTSIZE) ?
2542 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2543 It doesn't make sense when accessing arrays, so let's fix it here: */
2545 SPEC_USIGN (getSpec (operandType (right))) = 1;
2546 /* we can check for limits here */
2547 /* already done in SDCCast.c
2548 if (isOperandLiteral (right) &&
2551 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2553 werror (W_IDX_OUT_OF_BOUNDS,
2554 (int) operandLitValue (right) / getSize (ltype->next),
2559 ic = newiCode ('+', left, right);
2561 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2562 !IS_AGGREGATE (ltype->next) &&
2563 !IS_PTR (ltype->next))
2564 ? ltype : ltype->next), 0);
2566 if (!IS_AGGREGATE (ltype->next))
2568 IC_RESULT (ic)->isaddr = 1;
2569 IC_RESULT (ic)->aggr2ptr = 1;
2573 return IC_RESULT (ic);
2576 /*-----------------------------------------------------------------*/
2577 /* geniCodeStruct - generates intermediate code for structures */
2578 /*-----------------------------------------------------------------*/
2580 geniCodeStruct (operand * left, operand * right, bool islval)
2583 sym_link *type = operandType (left);
2584 sym_link *etype = getSpec (type);
2586 symbol *element = getStructElement (SPEC_STRUCT (etype),
2587 right->operand.symOperand);
2589 wassert(IS_SYMOP(right));
2591 /* add the offset */
2592 ic = newiCode ('+', left, operandFromLit (element->offset));
2594 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2596 /* preserve the storage & output class of the struct */
2597 /* as well as the volatile attribute */
2598 retype = getSpec (operandType (IC_RESULT (ic)));
2599 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2600 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2601 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2602 SPEC_CONST (retype) |= SPEC_CONST (etype);
2604 if (IS_PTR (element->type))
2605 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2607 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2610 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2613 /*-----------------------------------------------------------------*/
2614 /* geniCodePostInc - generate int code for Post increment */
2615 /*-----------------------------------------------------------------*/
2617 geniCodePostInc (operand * op)
2621 sym_link *optype = operandType (op);
2623 operand *rv = (IS_ITEMP (op) ?
2624 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2626 sym_link *rvtype = operandType (rv);
2629 /* if this is not an address we have trouble */
2632 werror (E_LVALUE_REQUIRED, "++");
2636 rOp = newiTempOperand (rvtype, 0);
2637 OP_SYMBOL(rOp)->noSpilLoc = 1;
2640 OP_SYMBOL(rv)->noSpilLoc = 1;
2642 geniCodeAssign (rOp, rv, 0, 0);
2644 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2646 werror(W_SIZEOF_VOID);
2647 if (IS_FLOAT (rvtype))
2648 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2650 if (IS_FIXED16X16 (rvtype))
2651 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2653 ic = newiCode ('+', rv, operandFromLit (size));
2655 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2658 geniCodeAssign (op, result, 0, 0);
2664 /*-----------------------------------------------------------------*/
2665 /* geniCodePreInc - generate code for preIncrement */
2666 /*-----------------------------------------------------------------*/
2668 geniCodePreInc (operand * op, bool lvalue)
2671 sym_link *optype = operandType (op);
2672 operand *rop = (IS_ITEMP (op) ?
2673 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2675 sym_link *roptype = operandType (rop);
2681 werror (E_LVALUE_REQUIRED, "++");
2685 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2687 werror(W_SIZEOF_VOID);
2688 if (IS_FLOAT (roptype))
2689 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2691 if (IS_FIXED16X16 (roptype))
2692 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2694 ic = newiCode ('+', rop, operandFromLit (size));
2695 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2698 (void) geniCodeAssign (op, result, 0, 0);
2699 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2705 /*-----------------------------------------------------------------*/
2706 /* geniCodePostDec - generates code for Post decrement */
2707 /*-----------------------------------------------------------------*/
2709 geniCodePostDec (operand * op)
2713 sym_link *optype = operandType (op);
2715 operand *rv = (IS_ITEMP (op) ?
2716 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2718 sym_link *rvtype = operandType (rv);
2721 /* if this is not an address we have trouble */
2724 werror (E_LVALUE_REQUIRED, "--");
2728 rOp = newiTempOperand (rvtype, 0);
2729 OP_SYMBOL(rOp)->noSpilLoc = 1;
2732 OP_SYMBOL(rv)->noSpilLoc = 1;
2734 geniCodeAssign (rOp, rv, 0, 0);
2736 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2738 werror(W_SIZEOF_VOID);
2739 if (IS_FLOAT (rvtype))
2740 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2742 if (IS_FIXED16X16 (rvtype))
2743 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2745 ic = newiCode ('-', rv, operandFromLit (size));
2747 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2750 geniCodeAssign (op, result, 0, 0);
2756 /*-----------------------------------------------------------------*/
2757 /* geniCodePreDec - generate code for pre decrement */
2758 /*-----------------------------------------------------------------*/
2760 geniCodePreDec (operand * op, bool lvalue)
2763 sym_link *optype = operandType (op);
2764 operand *rop = (IS_ITEMP (op) ?
2765 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2767 sym_link *roptype = operandType (rop);
2773 werror (E_LVALUE_REQUIRED, "--");
2777 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2779 werror(W_SIZEOF_VOID);
2780 if (IS_FLOAT (roptype))
2781 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2783 if (IS_FIXED16X16 (roptype))
2784 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2786 ic = newiCode ('-', rop, operandFromLit (size));
2787 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2790 (void) geniCodeAssign (op, result, 0, 0);
2791 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2798 /*-----------------------------------------------------------------*/
2799 /* geniCodeBitwise - gen int code for bitWise operators */
2800 /*-----------------------------------------------------------------*/
2802 geniCodeBitwise (operand * left, operand * right,
2803 int oper, sym_link * resType)
2807 left = geniCodeCast (resType, left, TRUE);
2808 right = geniCodeCast (resType, right, TRUE);
2810 ic = newiCode (oper, left, right);
2811 IC_RESULT (ic) = newiTempOperand (resType, 0);
2814 return IC_RESULT (ic);
2817 /*-----------------------------------------------------------------*/
2818 /* geniCodeAddressOf - gens icode for '&' address of operator */
2819 /*-----------------------------------------------------------------*/
2821 geniCodeAddressOf (operand * op)
2825 sym_link *optype = operandType (op);
2826 sym_link *opetype = getSpec (optype);
2828 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2830 op = operandFromOperand (op);
2835 /* lvalue check already done in decorateType */
2836 /* this must be a lvalue */
2837 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2838 /* werror (E_LVALUE_REQUIRED,"&"); */
2842 p = newLink (DECLARATOR);
2844 /* set the pointer depending on the storage class */
2845 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2847 p->next = copyLinkChain (optype);
2849 /* if already a temp */
2852 setOperandType (op, p);
2857 /* other wise make this of the type coming in */
2858 ic = newiCode (ADDRESS_OF, op, NULL);
2859 IC_RESULT (ic) = newiTempOperand (p, 1);
2860 IC_RESULT (ic)->isaddr = 0;
2862 return IC_RESULT (ic);
2865 /*-----------------------------------------------------------------*/
2866 /* setOClass - sets the output class depending on the pointer type */
2867 /*-----------------------------------------------------------------*/
2869 setOClass (sym_link * ptr, sym_link * spec)
2871 switch (DCL_TYPE (ptr))
2874 SPEC_OCLS (spec) = data;
2878 SPEC_OCLS (spec) = generic;
2882 SPEC_OCLS (spec) = xdata;
2886 SPEC_OCLS (spec) = code;
2890 SPEC_OCLS (spec) = idata;
2894 SPEC_OCLS (spec) = xstack;
2898 SPEC_OCLS (spec) = eeprom;
2907 /*-----------------------------------------------------------------*/
2908 /* geniCodeDerefPtr - dereference pointer with '*' */
2909 /*-----------------------------------------------------------------*/
2911 geniCodeDerefPtr (operand * op,int lvl)
2913 sym_link *rtype, *retype;
2914 sym_link *optype = operandType (op);
2916 // if this is an array then array access
2917 if (IS_ARRAY (optype)) {
2918 // don't worry, this will be optimized out later
2919 return geniCodeArray (op, operandFromLit (0), lvl);
2922 // just in case someone screws up
2923 wassert (IS_PTR (optype));
2925 if (IS_TRUE_SYMOP (op))
2928 op = geniCodeRValue (op, TRUE);
2931 /* now get rid of the pointer part */
2932 if (isLvaluereq(lvl) && IS_ITEMP (op))
2934 retype = getSpec (rtype = copyLinkChain (optype));
2938 retype = getSpec (rtype = copyLinkChain (optype->next));
2939 /* outputclass needs 2b updated */
2940 setOClass (optype, retype);
2943 op->isGptr = IS_GENPTR (optype);
2945 op->isaddr = (IS_PTR (rtype) ||
2946 IS_STRUCT (rtype) ||
2952 if (!isLvaluereq(lvl))
2953 op = geniCodeRValue (op, TRUE);
2955 setOperandType (op, rtype);
2960 /*-----------------------------------------------------------------*/
2961 /* geniCodeUnaryMinus - does a unary minus of the operand */
2962 /*-----------------------------------------------------------------*/
2964 geniCodeUnaryMinus (operand * op)
2967 sym_link *optype = operandType (op);
2969 if (IS_LITERAL (optype))
2970 return operandFromLit (-floatFromVal (op->operand.valOperand));
2972 ic = newiCode (UNARYMINUS, op, NULL);
2973 IC_RESULT (ic) = newiTempOperand (optype, 0);
2975 return IC_RESULT (ic);
2978 /*-----------------------------------------------------------------*/
2979 /* geniCodeLeftShift - gen i code for left shift */
2980 /*-----------------------------------------------------------------*/
2982 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2987 ic = newiCode (LEFT_OP, left, right);
2989 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2990 IC_RESULT (ic) = newiTempOperand (resType, 0);
2992 return IC_RESULT (ic);
2995 /*-----------------------------------------------------------------*/
2996 /* geniCodeRightShift - gen i code for right shift */
2997 /*-----------------------------------------------------------------*/
2999 geniCodeRightShift (operand * left, operand * right)
3003 ic = newiCode (RIGHT_OP, left, right);
3004 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3006 return IC_RESULT (ic);
3009 /*-----------------------------------------------------------------*/
3010 /* geniCodeLogic- logic code */
3011 /*-----------------------------------------------------------------*/
3013 geniCodeLogic (operand * left, operand * right, int op)
3017 sym_link *rtype = operandType (right);
3018 sym_link *ltype = operandType (left);
3020 /* left is integral type and right is literal then
3021 check if the literal value is within bounds */
3022 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3024 checkConstantRange(ltype,
3025 OP_VALUE(right), "compare operation", 1);
3028 /* if one operand is a pointer and the other is a literal generic void pointer,
3029 change the type of the literal generic void pointer to match the other pointer */
3030 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3031 && IS_PTR (rtype) && !IS_GENPTR(rtype))
3033 /* find left's definition */
3034 ic = (iCode *) setFirstItem (iCodeChain);
3037 if (((ic->op == CAST) || (ic->op == '='))
3038 && isOperandEqual(left, IC_RESULT (ic)))
3041 ic = setNextItem (iCodeChain);
3043 /* if casting literal to generic pointer, then cast to rtype instead */
3044 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3046 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3047 ltype = operandType(left);
3050 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3051 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3053 /* find right's definition */
3054 ic = (iCode *) setFirstItem (iCodeChain);
3057 if (((ic->op == CAST) || (ic->op == '='))
3058 && isOperandEqual(right, IC_RESULT (ic)))
3061 ic = setNextItem (iCodeChain);
3063 /* if casting literal to generic pointer, then cast to rtype instead */
3064 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3066 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3067 rtype = operandType(right);
3071 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
3073 ic = newiCode (op, left, right);
3074 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3076 /* if comparing float
3077 and not a '==' || '!=' || '&&' || '||' (these
3079 if (IS_FLOAT(ctype) &&
3086 /* if comparing a fixed type use support functions */
3087 if (IS_FIXED(ctype))
3091 return IC_RESULT (ic);
3094 /*-----------------------------------------------------------------*/
3095 /* geniCodeLogicAndOr - && || operations */
3096 /*-----------------------------------------------------------------*/
3098 geniCodeLogicAndOr (ast *tree, int lvl)
3102 symbol *falseLabel = newiTempLabel (NULL);
3103 symbol *trueLabel = newiTempLabel (NULL);
3104 symbol *exitLabel = newiTempLabel (NULL);
3105 operand *op, *result, *condition;
3107 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3108 They can be reenabled by executing the following block. If you find
3109 a decent optimization you could start right here:
3114 operand *leftOp, *rightOp;
3116 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3117 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3119 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3123 /* generate two IFX for the '&&' or '||' op */
3125 /* evaluate left operand */
3126 condition = ast2iCode (tree->left, lvl + 1);
3127 op = geniCodeRValue (condition, FALSE);
3129 /* test left operand */
3130 if (tree->opval.op == AND_OP)
3131 ic = newiCodeCondition (op, NULL, falseLabel);
3133 ic = newiCodeCondition (op, trueLabel, NULL);
3136 /* evaluate right operand */
3137 condition = ast2iCode (tree->right, lvl + 1);
3138 op = geniCodeRValue (condition, FALSE);
3140 /* test right operand */
3141 ic = newiCodeCondition (op, trueLabel, NULL);
3144 /* store 0 or 1 in result */
3145 type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3146 result = newiTempOperand (type, 1);
3148 geniCodeLabel (falseLabel);
3149 geniCodeAssign (result, operandFromLit (0), 0, 0);
3150 /* generate an unconditional goto */
3151 geniCodeGoto (exitLabel);
3153 geniCodeLabel (trueLabel);
3154 geniCodeAssign (result, operandFromLit (1), 0, 0);
3156 geniCodeLabel (exitLabel);
3161 /*-----------------------------------------------------------------*/
3162 /* geniCodeUnary - for a generic unary operation */
3163 /*-----------------------------------------------------------------*/
3165 geniCodeUnary (operand * op, int oper)
3167 iCode *ic = newiCode (oper, op, NULL);
3169 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3171 return IC_RESULT (ic);
3174 /*-----------------------------------------------------------------*/
3175 /* geniCodeBinary - for a generic binary operation */
3176 /*-----------------------------------------------------------------*/
3178 geniCodeBinary (operand * left, operand * right, int oper)
3180 iCode *ic = newiCode (oper, left, right);
3182 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3184 return IC_RESULT (ic);
3187 /*-----------------------------------------------------------------*/
3188 /* geniCodeConditional - geniCode for '?' ':' operation */
3189 /*-----------------------------------------------------------------*/
3191 geniCodeConditional (ast * tree,int lvl)
3194 symbol *falseLabel = newiTempLabel (NULL);
3195 symbol *exitLabel = newiTempLabel (NULL);
3196 operand *cond = ast2iCode (tree->left,lvl+1);
3197 operand *true, *false, *result;
3199 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3203 true = ast2iCode (tree->right->left,lvl+1);
3205 /* move the value to a new Operand */
3206 result = newiTempOperand (tree->right->ftype, 0);
3207 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3209 /* generate an unconditional goto */
3210 geniCodeGoto (exitLabel);
3212 /* now for the right side */
3213 geniCodeLabel (falseLabel);
3215 false = ast2iCode (tree->right->right,lvl+1);
3216 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3218 /* create the exit label */
3219 geniCodeLabel (exitLabel);
3224 /*-----------------------------------------------------------------*/
3225 /* geniCodeAssign - generate code for assignment */
3226 /*-----------------------------------------------------------------*/
3228 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3231 sym_link *ltype = operandType (left);
3232 sym_link *rtype = operandType (right);
3234 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3236 werror (E_LVALUE_REQUIRED, "assignment");
3240 /* left is integral type and right is literal then
3241 check if the literal value is within bounds */
3242 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3244 checkConstantRange(ltype,
3245 OP_VALUE(right), "= operation", 0);
3248 /* if the left & right type don't exactly match */
3249 /* if pointer set then make sure the check is
3250 done with the type & not the pointer */
3251 /* then cast rights type to left */
3253 /* first check the type for pointer assignement */
3254 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3255 compareType (ltype, rtype) <= 0)
3257 if (compareType (ltype->next, rtype) < 0)
3258 right = geniCodeCast (ltype->next, right, TRUE);
3260 else if (compareType (ltype, rtype) < 0)
3261 right = geniCodeCast (ltype, right, TRUE);
3263 /* If left is a true symbol & ! volatile
3264 create an assignment to temporary for
3265 the right & then assign this temporary
3266 to the symbol. This is SSA (static single
3267 assignment). Isn't it simple and folks have
3268 published mountains of paper on it */
3269 if (IS_TRUE_SYMOP (left) &&
3270 !isOperandVolatile (left, FALSE) &&
3271 isOperandGlobal (left))
3275 if (IS_TRUE_SYMOP (right))
3276 sym = OP_SYMBOL (right);
3277 ic = newiCode ('=', NULL, right);
3278 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3279 SPIL_LOC (right) = sym;
3283 ic = newiCode ('=', NULL, right);
3284 IC_RESULT (ic) = left;
3287 /* if left isgptr flag is set then support
3288 routine will be required */
3292 ic->nosupdate = nosupdate;
3296 /*-----------------------------------------------------------------*/
3297 /* geniCodeDummyRead - generate code for dummy read */
3298 /*-----------------------------------------------------------------*/
3300 geniCodeDummyRead (operand * op)
3303 sym_link *type = operandType (op);
3305 if (!IS_VOLATILE(type))
3308 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3314 /*-----------------------------------------------------------------*/
3315 /* geniCodeSEParms - generate code for side effecting fcalls */
3316 /*-----------------------------------------------------------------*/
3318 geniCodeSEParms (ast * parms,int lvl)
3323 if (parms->type == EX_OP && parms->opval.op == PARAM)
3325 geniCodeSEParms (parms->left,lvl);
3326 geniCodeSEParms (parms->right,lvl);
3330 /* hack don't like this but too lazy to think of
3332 if (IS_ADDRESS_OF_OP (parms))
3333 parms->left->lvalue = 1;
3335 if (IS_CAST_OP (parms) &&
3336 IS_PTR (parms->ftype) &&
3337 IS_ADDRESS_OF_OP (parms->right))
3338 parms->right->left->lvalue = 1;
3340 parms->opval.oprnd =
3341 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3343 parms->type = EX_OPERAND;
3344 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3345 SPEC_ARGREG(parms->ftype);
3348 /*-----------------------------------------------------------------*/
3349 /* geniCodeParms - generates parameters */
3350 /*-----------------------------------------------------------------*/
3352 geniCodeParms (ast * parms, value *argVals, int *stack,
3353 sym_link * ftype, int lvl)
3361 if (argVals==NULL) {
3363 argVals = FUNC_ARGS (ftype);
3366 /* if this is a param node then do the left & right */
3367 if (parms->type == EX_OP && parms->opval.op == PARAM)
3369 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3370 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3374 /* get the parameter value */
3375 if (parms->type == EX_OPERAND)
3376 pval = parms->opval.oprnd;
3379 /* maybe this else should go away ?? */
3380 /* hack don't like this but too lazy to think of
3382 if (IS_ADDRESS_OF_OP (parms))
3383 parms->left->lvalue = 1;
3385 if (IS_CAST_OP (parms) &&
3386 IS_PTR (parms->ftype) &&
3387 IS_ADDRESS_OF_OP (parms->right))
3388 parms->right->left->lvalue = 1;
3390 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3393 /* if register parm then make it a send */
3394 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3395 IFFUNC_ISBUILTIN(ftype))
3397 ic = newiCode (SEND, pval, NULL);
3398 ic->argreg = SPEC_ARGREG(parms->etype);
3399 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3404 /* now decide whether to push or assign */
3405 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3409 operand *top = operandFromSymbol (argVals->sym);
3410 /* clear useDef and other bitVectors */
3411 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3412 geniCodeAssign (top, pval, 1, 0);
3416 sym_link *p = operandType (pval);
3418 ic = newiCode (IPUSH, pval, NULL);
3420 /* update the stack adjustment */
3421 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3426 argVals=argVals->next;
3430 /*-----------------------------------------------------------------*/
3431 /* geniCodeCall - generates temp code for calling */
3432 /*-----------------------------------------------------------------*/
3434 geniCodeCall (operand * left, ast * parms,int lvl)
3438 sym_link *type, *etype;
3442 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3443 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3444 werror (E_FUNCTION_EXPECTED);
3445 return operandFromValue(valueFromLit(0));
3448 /* take care of parameters with side-effecting
3449 function calls in them, this is required to take care
3450 of overlaying function parameters */
3451 geniCodeSEParms (parms,lvl);
3453 ftype = operandType (left);
3454 if (IS_FUNCPTR (ftype))
3455 ftype = ftype->next;
3457 /* first the parameters */
3458 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3460 /* now call : if symbol then pcall */
3461 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3462 ic = newiCode (PCALL, left, NULL);
3464 ic = newiCode (CALL, left, NULL);
3467 type = copyLinkChain (ftype->next);
3468 etype = getSpec (type);
3469 SPEC_EXTR (etype) = 0;
3470 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3474 /* stack adjustment after call */
3475 ic->parmBytes = stack;
3480 /*-----------------------------------------------------------------*/
3481 /* geniCodeReceive - generate intermediate code for "receive" */
3482 /*-----------------------------------------------------------------*/
3484 geniCodeReceive (value * args, operand * func)
3486 unsigned char paramByteCounter = 0;
3488 /* for all arguments that are passed in registers */
3491 if (IS_REGPARM (args->etype))
3493 operand *opr = operandFromValue (args);
3495 symbol *sym = OP_SYMBOL (opr);
3498 /* we will use it after all optimizations
3499 and before liveRange calculation */
3500 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3503 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3504 options.stackAuto == 0 &&
3505 (!(options.model == MODEL_FLAT24)) )
3510 opl = newiTempOperand (args->type, 0);
3512 sym->reqv->key = sym->key;
3513 OP_SYMBOL (sym->reqv)->key = sym->key;
3514 OP_SYMBOL (sym->reqv)->isreqv = 1;
3515 OP_SYMBOL (sym->reqv)->islocal = 0;
3516 SPIL_LOC (sym->reqv) = sym;
3520 ic = newiCode (RECEIVE, func, NULL);
3521 ic->argreg = SPEC_ARGREG(args->etype);
3522 if (ic->argreg == 1) {
3523 currFunc->recvSize = getSize (sym->type);
3525 IC_RESULT (ic) = opr;
3527 /* misuse of parmBytes (normally used for functions)
3528 * to save estimated stack position of this argument.
3529 * Normally this should be zero for RECEIVE iCodes.
3530 * No idea if this causes side effects on other ports. - dw
3532 ic->parmBytes = paramByteCounter;
3534 /* what stack position do we have? */
3535 paramByteCounter += getSize (sym->type);
3544 /*-----------------------------------------------------------------*/
3545 /* geniCodeFunctionBody - create the function body */
3546 /*-----------------------------------------------------------------*/
3548 geniCodeFunctionBody (ast * tree,int lvl)
3555 /* reset the auto generation */
3561 func = ast2iCode (tree->left,lvl+1);
3562 fetype = getSpec (operandType (func));
3564 savelineno = lineno;
3565 lineno = OP_SYMBOL (func)->lineDef;
3566 /* create an entry label */
3567 geniCodeLabel (entryLabel);
3568 lineno = savelineno;
3570 /* create a proc icode */
3571 ic = newiCode (FUNCTION, func, NULL);
3572 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3577 /* for all parameters that are passed
3578 on registers add a "receive" */
3579 geniCodeReceive (tree->values.args, func);
3581 /* generate code for the body */
3582 ast2iCode (tree->right,lvl+1);
3584 /* create a label for return */
3585 geniCodeLabel (returnLabel);
3587 /* now generate the end proc */
3588 ic = newiCode (ENDFUNCTION, func, NULL);
3594 /*-----------------------------------------------------------------*/
3595 /* geniCodeReturn - gen icode for 'return' statement */
3596 /*-----------------------------------------------------------------*/
3598 geniCodeReturn (operand * op)
3602 /* if the operand is present force an rvalue */
3604 op = geniCodeRValue (op, FALSE);
3606 ic = newiCode (RETURN, op, NULL);
3610 /*-----------------------------------------------------------------*/
3611 /* geniCodeIfx - generates code for extended if statement */
3612 /*-----------------------------------------------------------------*/
3614 geniCodeIfx (ast * tree,int lvl)
3617 operand *condition = ast2iCode (tree->left,lvl+1);
3620 /* if condition is null then exit */
3624 condition = geniCodeRValue (condition, FALSE);
3626 cetype = getSpec (operandType (condition));
3627 /* if the condition is a literal */
3628 if (IS_LITERAL (cetype))
3630 if (floatFromVal (condition->operand.valOperand))
3632 if (tree->trueLabel)
3633 geniCodeGoto (tree->trueLabel);
3639 if (tree->falseLabel)
3640 geniCodeGoto (tree->falseLabel);
3647 if (tree->trueLabel)
3649 ic = newiCodeCondition (condition,
3654 if (tree->falseLabel)
3655 geniCodeGoto (tree->falseLabel);
3659 ic = newiCodeCondition (condition,
3666 ast2iCode (tree->right,lvl+1);
3669 /*-----------------------------------------------------------------*/
3670 /* geniCodeJumpTable - tries to create a jump table for switch */
3671 /*-----------------------------------------------------------------*/
3673 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3675 int min, max, cnt = 1;
3682 int needRangeCheck = !optimize.noJTabBoundary
3683 || tree->values.switchVals.swDefault;
3684 sym_link *cetype = getSpec (operandType (cond));
3685 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3686 int sizeofMatchJump, sizeofJumpTable;
3689 if (!tree || !caseVals)
3692 /* the criteria for creating a jump table is */
3693 /* all integer numbers between the maximum & minimum must */
3694 /* be present , the maximum value should not exceed 255 */
3695 /* If not all integer numbers are present the algorithm */
3696 /* inserts jumps to the default label for the missing numbers */
3697 /* and decides later whether it is worth it */
3698 min = (int) floatFromVal (vch = caseVals);
3705 max = (int) floatFromVal (vch);
3707 /* Exit if the range is too large to handle with a jump table. */
3708 if (1 + max - min > port->jumptableCost.maxCount)
3711 switch (getSize (operandType (cond)))
3713 case 1: sizeIndex = 0; break;
3714 case 2: sizeIndex = 1; break;
3715 case 4: sizeIndex = 2; break;
3719 /* Compute the size cost of the range check and subtraction. */
3721 sizeofZeroMinCost = 0;
3725 if (!(min==0 && IS_UNSIGNED (cetype)))
3726 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3727 if (!IS_UNSIGNED (cetype))
3728 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3729 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3732 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3734 /* If the size cost of handling a non-zero minimum exceeds the */
3735 /* cost of extending the range down to zero, then it might be */
3736 /* better to extend the range to zero. */
3737 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3738 >= (min * port->jumptableCost.sizeofElement))
3740 /* Only extend the jump table if it would still be manageable. */
3741 if (1 + max <= port->jumptableCost.maxCount)
3744 if (IS_UNSIGNED (cetype))
3747 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3751 /* Compute the total size cost of a jump table. */
3752 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3753 + port->jumptableCost.sizeofDispatch
3754 + sizeofMinCost + sizeofMaxCost;
3756 /* Compute the total size cost of a match & jump sequence */
3757 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3759 /* If the size cost of the jump table is uneconomical then exit */
3760 if (sizeofMatchJump < sizeofJumpTable)
3763 /* The jump table is preferable. */
3765 /* First, a label for the default or missing cases. */
3766 if (tree->values.switchVals.swDefault)
3768 SNPRINTF (buffer, sizeof(buffer),
3770 tree->values.switchVals.swNum);
3774 SNPRINTF (buffer, sizeof(buffer),
3776 tree->values.switchVals.swNum);
3778 falseLabel = newiTempLabel (buffer);
3780 /* Build the list of labels for the jump table. */
3782 t = (int) floatFromVal (vch);
3783 for (i=min; i<=max; i++)
3787 /* Explicit case: make a new label for it. */
3788 SNPRINTF (buffer, sizeof(buffer),
3790 tree->values.switchVals.swNum,
3792 addSet (&labels, newiTempLabel (buffer));
3795 t = (int) floatFromVal (vch);
3799 /* Implicit case: use the default label. */
3800 addSet (&labels, falseLabel);
3804 /* first we rule out the boundary conditions */
3805 /* if only optimization says so */
3808 sym_link *cetype = getSpec (operandType (cond));
3809 /* no need to check the lower bound if
3810 the condition is unsigned & minimum value is zero */
3811 if (!(min == 0 && IS_UNSIGNED (cetype)))
3813 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3814 ic = newiCodeCondition (boundary, falseLabel, NULL);
3818 /* now for upper bounds */
3819 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3820 ic = newiCodeCondition (boundary, falseLabel, NULL);
3824 /* if the min is not zero then we no make it zero */
3827 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3828 if (!IS_LITERAL(getSpec(operandType(cond))))
3829 setOperandType (cond, UCHARTYPE);
3832 /* now create the jumptable */
3833 ic = newiCode (JUMPTABLE, NULL, NULL);
3834 IC_JTCOND (ic) = cond;
3835 IC_JTLABELS (ic) = labels;
3840 /*-----------------------------------------------------------------*/
3841 /* geniCodeSwitch - changes a switch to a if statement */
3842 /*-----------------------------------------------------------------*/
3844 geniCodeSwitch (ast * tree,int lvl)
3847 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3848 value *caseVals = tree->values.switchVals.swVals;
3849 symbol *trueLabel, *falseLabel;
3851 /* If the condition is a literal, then just jump to the */
3852 /* appropriate case label. */
3853 if (IS_LITERAL(getSpec(operandType(cond))))
3855 int switchVal, caseVal;
3857 switchVal = (int) floatFromVal (cond->operand.valOperand);
3860 caseVal = (int) floatFromVal (caseVals);
3861 if (caseVal == switchVal)
3863 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3864 tree->values.switchVals.swNum, caseVal);
3865 trueLabel = newiTempLabel (buffer);
3866 geniCodeGoto (trueLabel);
3869 caseVals = caseVals->next;
3871 goto defaultOrBreak;
3874 /* If cond is volatile, it might change while we are trying to */
3875 /* find the matching case. To avoid this possibility, make a */
3876 /* non-volatile copy to use instead. */
3877 if (IS_OP_VOLATILE (cond))
3882 newcond = newiTempOperand (operandType (cond), TRUE);
3883 newcond->isvolatile = 0;
3884 ic = newiCode ('=', NULL, cond);
3885 IC_RESULT (ic) = newcond;
3890 /* if we can make this a jump table */
3891 if (geniCodeJumpTable (cond, caseVals, tree))
3892 goto jumpTable; /* no need for the comparison */
3894 /* for the cases defined do */
3898 operand *compare = geniCodeLogic (cond,
3899 operandFromValue (caseVals),
3902 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3903 tree->values.switchVals.swNum,
3904 (int) floatFromVal (caseVals));
3905 trueLabel = newiTempLabel (buffer);
3907 ic = newiCodeCondition (compare, trueLabel, NULL);
3909 caseVals = caseVals->next;
3914 /* if default is present then goto break else break */
3915 if (tree->values.switchVals.swDefault)
3917 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3921 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3924 falseLabel = newiTempLabel (buffer);
3925 geniCodeGoto (falseLabel);
3928 ast2iCode (tree->right,lvl+1);
3931 /*-----------------------------------------------------------------*/
3932 /* geniCodeInline - intermediate code for inline assembler */
3933 /*-----------------------------------------------------------------*/
3935 geniCodeInline (ast * tree)
3939 ic = newiCode (INLINEASM, NULL, NULL);
3940 IC_INLINE (ic) = tree->values.inlineasm;
3944 /*-----------------------------------------------------------------*/
3945 /* geniCodeArrayInit - intermediate code for array initializer */
3946 /*-----------------------------------------------------------------*/
3948 geniCodeArrayInit (ast * tree, operand *array)
3952 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3953 ic = newiCode (ARRAYINIT, array, NULL);
3954 IC_ARRAYILIST (ic) = tree->values.constlist;
3956 operand *left=newOperand(), *right=newOperand();
3957 left->type=right->type=SYMBOL;
3958 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3959 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3960 ic = newiCode (ARRAYINIT, left, right);
3965 /*-----------------------------------------------------------------*/
3966 /* geniCodeCritical - intermediate code for a critical statement */
3967 /*-----------------------------------------------------------------*/
3969 geniCodeCritical (ast *tree, int lvl)
3975 if (!options.stackAuto)
3977 type = newLink(SPECIFIER);
3978 SPEC_VOLATILE(type) = 1;
3979 SPEC_NOUN(type) = V_BIT;
3980 SPEC_SCLS(type) = S_BIT;
3981 SPEC_BLEN(type) = 1;
3982 SPEC_BSTR(type) = 0;
3983 op = newiTempOperand(type, 1);
3986 /* If op is NULL, the original interrupt state will saved on */
3987 /* the stack. Otherwise, it will be saved in op. */
3989 /* Generate a save of the current interrupt state & disable */
3990 ic = newiCode (CRITICAL, NULL, NULL);
3991 IC_RESULT (ic) = op;
3994 /* Generate the critical code sequence */
3995 if (tree->left && tree->left->type == EX_VALUE)
3996 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3998 ast2iCode (tree->left,lvl+1);
4000 /* Generate a restore of the original interrupt state */
4001 ic = newiCode (ENDCRITICAL, NULL, op);
4005 /*-----------------------------------------------------------------*/
4006 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
4007 /* particular case. Ie : assigning or dereferencing array or ptr */
4008 /*-----------------------------------------------------------------*/
4009 set * lvaluereqSet = NULL;
4010 typedef struct lvalItem
4017 /*-----------------------------------------------------------------*/
4018 /* addLvaluereq - add a flag for lvalreq for current ast level */
4019 /*-----------------------------------------------------------------*/
4020 void addLvaluereq(int lvl)
4022 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4025 addSetHead(&lvaluereqSet,lpItem);
4028 /*-----------------------------------------------------------------*/
4029 /* delLvaluereq - del a flag for lvalreq for current ast level */
4030 /*-----------------------------------------------------------------*/
4034 lpItem = getSet(&lvaluereqSet);
4035 if(lpItem) Safe_free(lpItem);
4037 /*-----------------------------------------------------------------*/
4038 /* clearLvaluereq - clear lvalreq flag */
4039 /*-----------------------------------------------------------------*/
4040 void clearLvaluereq()
4043 lpItem = peekSet(lvaluereqSet);
4044 if(lpItem) lpItem->req = 0;
4046 /*-----------------------------------------------------------------*/
4047 /* getLvaluereq - get the last lvalreq level */
4048 /*-----------------------------------------------------------------*/
4049 int getLvaluereqLvl()
4052 lpItem = peekSet(lvaluereqSet);
4053 if(lpItem) return lpItem->lvl;
4056 /*-----------------------------------------------------------------*/
4057 /* isLvaluereq - is lvalreq valid for this level ? */
4058 /*-----------------------------------------------------------------*/
4059 int isLvaluereq(int lvl)
4062 lpItem = peekSet(lvaluereqSet);
4063 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4067 /*-----------------------------------------------------------------*/
4068 /* ast2iCode - creates an icodeList from an ast */
4069 /*-----------------------------------------------------------------*/
4071 ast2iCode (ast * tree,int lvl)
4073 operand *left = NULL;
4074 operand *right = NULL;
4078 /* set the global variables for filename & line number */
4080 filename = tree->filename;
4082 lineno = tree->lineno;
4084 block = tree->block;
4086 scopeLevel = tree->level;
4088 seqPoint = tree->seqPoint;
4090 if (tree->type == EX_VALUE)
4091 return operandFromValue (tree->opval.val);
4093 if (tree->type == EX_LINK)
4094 return operandFromLink (tree->opval.lnk);
4096 /* if we find a nullop */
4097 if (tree->type == EX_OP &&
4098 (tree->opval.op == NULLOP ||
4099 tree->opval.op == BLOCK))
4101 if (tree->left && tree->left->type == EX_VALUE)
4102 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4104 ast2iCode (tree->left,lvl+1);
4105 if (tree->right && tree->right->type == EX_VALUE)
4106 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4108 ast2iCode (tree->right,lvl+1);
4112 /* special cases for not evaluating */
4113 if (tree->opval.op != ':' &&
4114 tree->opval.op != '?' &&
4115 tree->opval.op != CALL &&
4116 tree->opval.op != IFX &&
4117 tree->opval.op != AND_OP &&
4118 tree->opval.op != OR_OP &&
4119 tree->opval.op != LABEL &&
4120 tree->opval.op != GOTO &&
4121 tree->opval.op != SWITCH &&
4122 tree->opval.op != FUNCTION &&
4123 tree->opval.op != INLINEASM &&
4124 tree->opval.op != CRITICAL)
4127 if (IS_ASSIGN_OP (tree->opval.op) ||
4128 IS_DEREF_OP (tree) ||
4129 (tree->opval.op == '&' && !tree->right) ||
4130 tree->opval.op == PTR_OP)
4133 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4134 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4137 left = operandFromAst (tree->left,lvl);
4139 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4140 left = geniCodeRValue (left, TRUE);
4144 left = operandFromAst (tree->left,lvl);
4146 if (tree->opval.op == INC_OP ||
4147 tree->opval.op == DEC_OP)
4150 right = operandFromAst (tree->right,lvl);
4155 right = operandFromAst (tree->right,lvl);
4159 /* now depending on the type of operand */
4160 /* this will be a biggy */
4161 switch (tree->opval.op)
4164 case '[': /* array operation */
4166 //sym_link *ltype = operandType (left);
4167 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4168 left = geniCodeRValue (left, FALSE);
4169 right = geniCodeRValue (right, TRUE);
4172 return geniCodeArray (left, right,lvl);
4174 case '.': /* structure dereference */
4175 if (IS_PTR (operandType (left)))
4176 left = geniCodeRValue (left, TRUE);
4178 left = geniCodeRValue (left, FALSE);
4180 return geniCodeStruct (left, right, tree->lvalue);
4182 case PTR_OP: /* structure pointer dereference */
4185 pType = operandType (left);
4186 left = geniCodeRValue (left, TRUE);
4188 setOClass (pType, getSpec (operandType (left)));
4191 return geniCodeStruct (left, right, tree->lvalue);
4193 case INC_OP: /* increment operator */
4195 return geniCodePostInc (left);
4197 return geniCodePreInc (right, tree->lvalue);
4199 case DEC_OP: /* decrement operator */
4201 return geniCodePostDec (left);
4203 return geniCodePreDec (right, tree->lvalue);
4205 case '&': /* bitwise and or address of operator */
4207 { /* this is a bitwise operator */
4208 left = geniCodeRValue (left, FALSE);
4209 right = geniCodeRValue (right, FALSE);
4210 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4213 return geniCodeAddressOf (left);
4215 case '|': /* bitwise or & xor */
4217 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4218 geniCodeRValue (right, FALSE),
4223 return geniCodeDivision (geniCodeRValue (left, FALSE),
4224 geniCodeRValue (right, FALSE),
4225 getResultTypeFromType (tree->ftype));
4228 return geniCodeModulus (geniCodeRValue (left, FALSE),
4229 geniCodeRValue (right, FALSE),
4230 getResultTypeFromType (tree->ftype));
4233 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4234 geniCodeRValue (right, FALSE),
4235 getResultTypeFromType (tree->ftype));
4237 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4241 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4242 geniCodeRValue (right, FALSE),
4243 getResultTypeFromType (tree->ftype));
4245 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4249 return geniCodeAdd (geniCodeRValue (left, FALSE),
4250 geniCodeRValue (right, FALSE),
4251 getResultTypeFromType (tree->ftype),
4254 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4257 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4258 geniCodeRValue (right, FALSE),
4259 getResultTypeFromType (tree->ftype));
4262 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4263 geniCodeRValue (right, FALSE));
4265 #if 0 // this indeed needs a second thought
4269 // let's keep this simple: get the rvalue we need
4270 op=geniCodeRValue (right, FALSE);
4271 // now cast it to whatever we want
4272 op=geniCodeCast (operandType(left), op, FALSE);
4273 // if this is going to be used as an lvalue, make it so
4279 #else // bug #604575, is it a bug ????
4280 return geniCodeCast (operandType (left),
4281 geniCodeRValue (right, FALSE), FALSE);
4288 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4293 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4294 setOperandType (op, UCHARTYPE);
4301 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4302 geniCodeRValue (right, FALSE),
4304 setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4309 return geniCodeLogicAndOr (tree, lvl);
4316 /* different compilers (even different gccs) evaluate
4317 the two calls in a different order. to get the same
4318 result on all machines we've to specify a clear sequence.
4319 return geniCodeLogic (geniCodeRValue (left, FALSE),
4320 geniCodeRValue (right, FALSE),
4324 operand *leftOp, *rightOp;
4326 leftOp = geniCodeRValue (left , FALSE);
4327 rightOp = geniCodeRValue (right, FALSE);
4329 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4332 return geniCodeConditional (tree,lvl);
4335 return operandFromLit (getSize (tree->right->ftype));
4339 sym_link *rtype = operandType (right);
4340 sym_link *ltype = operandType (left);
4341 if (IS_PTR (rtype) && IS_ITEMP (right)
4342 && right->isaddr && compareType (rtype->next, ltype) == 1)
4343 right = geniCodeRValue (right, TRUE);
4345 right = geniCodeRValue (right, FALSE);
4347 geniCodeAssign (left, right, 0, 1);
4352 geniCodeAssign (left,
4353 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4355 geniCodeRValue (right, FALSE),
4356 getResultTypeFromType (tree->ftype)),
4361 geniCodeAssign (left,
4362 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4364 geniCodeRValue (right, FALSE),
4365 getResultTypeFromType (tree->ftype)),
4369 geniCodeAssign (left,
4370 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4372 geniCodeRValue (right, FALSE),
4373 getResultTypeFromType (tree->ftype)),
4377 sym_link *rtype = operandType (right);
4378 sym_link *ltype = operandType (left);
4379 if (IS_PTR (rtype) && IS_ITEMP (right)
4380 && right->isaddr && compareType (rtype->next, ltype) == 1)
4381 right = geniCodeRValue (right, TRUE);
4383 right = geniCodeRValue (right, FALSE);
4386 return geniCodeAssign (left,
4387 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4390 getResultTypeFromType (tree->ftype),
4396 sym_link *rtype = operandType (right);
4397 sym_link *ltype = operandType (left);
4398 if (IS_PTR (rtype) && IS_ITEMP (right)
4399 && right->isaddr && compareType (rtype->next, ltype) == 1)
4401 right = geniCodeRValue (right, TRUE);
4405 right = geniCodeRValue (right, FALSE);
4408 geniCodeAssign (left,
4409 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4412 getResultTypeFromType (tree->ftype)),
4417 geniCodeAssign (left,
4418 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4420 geniCodeRValue (right, FALSE),
4421 getResultTypeFromType (tree->ftype)),
4425 geniCodeAssign (left,
4426 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4428 geniCodeRValue (right, FALSE)), 0, 1);
4431 geniCodeAssign (left,
4432 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4434 geniCodeRValue (right, FALSE),
4436 operandType (left)), 0, 1);
4439 geniCodeAssign (left,
4440 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4442 geniCodeRValue (right, FALSE),
4444 operandType (left)), 0, 1);
4447 geniCodeAssign (left,
4448 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4450 geniCodeRValue (right, FALSE),
4452 operandType (left)), 0, 1);
4454 return geniCodeRValue (right, FALSE);
4457 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4460 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4461 return ast2iCode (tree->right,lvl+1);
4464 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4465 return ast2iCode (tree->right,lvl+1);
4468 geniCodeFunctionBody (tree,lvl);
4472 geniCodeReturn (right);
4476 geniCodeIfx (tree,lvl);
4480 geniCodeSwitch (tree,lvl);
4484 geniCodeInline (tree);
4488 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4492 geniCodeCritical (tree, lvl);
4498 /*-----------------------------------------------------------------*/
4499 /* reverseICChain - gets from the list and creates a linkedlist */
4500 /*-----------------------------------------------------------------*/
4507 while ((loop = getSet (&iCodeChain)))
4519 /*-----------------------------------------------------------------*/
4520 /* iCodeFromAst - given an ast will convert it to iCode */
4521 /*-----------------------------------------------------------------*/
4523 iCodeFromAst (ast * tree)
4525 returnLabel = newiTempLabel ("_return");
4526 entryLabel = newiTempLabel ("_entry");
4528 return reverseiCChain ();
4531 static const char *opTypeToStr(OPTYPE op)
4535 case SYMBOL: return "symbol";
4536 case VALUE: return "value";
4537 case TYPE: return "type";
4539 return "undefined type";
4543 operand *validateOpType(operand *op,
4550 if (op && op->type == type)
4555 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4556 " expected %s, got %s\n",
4557 macro, args, file, line,
4558 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4560 return op; // never reached, makes compiler happy.