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;
42 symbol *returnLabel; /* function return label */
43 symbol *entryLabel; /* function entry label */
45 /*-----------------------------------------------------------------*/
46 /* forward definition of some functions */
47 operand *geniCodeDivision (operand *, operand *);
48 operand *geniCodeAssign (operand *, operand *, int);
49 operand *geniCodeArray (operand *, operand *,int);
50 operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
55 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
56 /* forward definition of ic print functions */
57 PRINTFUNC (picGetValueAtAddr);
58 PRINTFUNC (picSetValueAtAddr);
59 PRINTFUNC (picAddrOf);
60 PRINTFUNC (picGeneric);
61 PRINTFUNC (picGenericOne);
63 PRINTFUNC (picAssign);
67 PRINTFUNC (picJumpTable);
68 PRINTFUNC (picInline);
69 PRINTFUNC (picReceive);
71 iCodeTable codeTable[] =
73 {'!', "not", picGenericOne, NULL},
74 {'~', "~", picGenericOne, NULL},
75 {RRC, "rrc", picGenericOne, NULL},
76 {RLC, "rlc", picGenericOne, NULL},
77 {GETHBIT, "ghbit", picGenericOne, NULL},
78 {UNARYMINUS, "-", picGenericOne, NULL},
79 {IPUSH, "push", picGenericOne, NULL},
80 {IPOP, "pop", picGenericOne, NULL},
81 {CALL, "call", picGenericOne, NULL},
82 {PCALL, "pcall", picGenericOne, NULL},
83 {FUNCTION, "proc", picGenericOne, NULL},
84 {ENDFUNCTION, "eproc", picGenericOne, NULL},
85 {RETURN, "ret", picGenericOne, NULL},
86 {'+', "+", picGeneric, NULL},
87 {'-', "-", picGeneric, NULL},
88 {'*', "*", picGeneric, NULL},
89 {'/', "/", picGeneric, NULL},
90 {'%', "%", picGeneric, NULL},
91 {'>', ">", picGeneric, NULL},
92 {'<', "<", picGeneric, NULL},
93 {LE_OP, "<=", picGeneric, NULL},
94 {GE_OP, ">=", picGeneric, NULL},
95 {EQ_OP, "==", picGeneric, NULL},
96 {NE_OP, "!=", picGeneric, NULL},
97 {AND_OP, "&&", picGeneric, NULL},
98 {OR_OP, "||", picGeneric, NULL},
99 {'^', "^", picGeneric, NULL},
100 {'|', "|", picGeneric, NULL},
101 {BITWISEAND, "&", picGeneric, NULL},
102 {LEFT_OP, "<<", picGeneric, NULL},
103 {RIGHT_OP, ">>", picGeneric, NULL},
104 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
105 {ADDRESS_OF, "&", picAddrOf, NULL},
106 {CAST, "<>", picCast, NULL},
107 {'=', ":=", picAssign, NULL},
108 {LABEL, "", picLabel, NULL},
109 {GOTO, "", picGoto, NULL},
110 {JUMPTABLE, "jtab", picJumpTable, NULL},
111 {IFX, "if", picIfx, NULL},
112 {INLINEASM, "", picInline, NULL},
113 {RECEIVE, "recv", picReceive, NULL},
114 {SEND, "send", picGenericOne, NULL},
115 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
118 // this makes it more easy to catch bugs
119 struct bitVect *OP_DEFS(struct operand *op) {
120 wassert (IS_SYMOP(op));
121 return OP_SYMBOL(op)->defs;
123 struct bitVect *OP_DEFS_SET(struct operand *op, struct bitVect *bv) {
124 wassert (IS_SYMOP(op));
125 OP_SYMBOL(op)->defs=bv;
128 struct bitVect *OP_USES(struct operand *op) {
129 wassert (IS_SYMOP(op));
130 return OP_SYMBOL(op)->uses;
132 struct bitVect *OP_USES_SET(struct operand *op, struct bitVect *bv) {
133 wassert (IS_SYMOP(op));
134 OP_SYMBOL(op)->uses=bv;
138 /*-----------------------------------------------------------------*/
139 /* checkConstantRange: check a constant against the type */
140 /*-----------------------------------------------------------------*/
142 /* pedantic=0: allmost anything is allowed as long as the absolute
143 value is within the bit range of the type, and -1 is treated as
144 0xf..f for unsigned types (e.g. in assign)
145 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
146 pedantic>1: "char c=200" is not allowed (evaluates to -56)
149 void checkConstantRange(sym_link *ltype, value *val, char *msg,
156 max = pow ((double)2.0, (double)bitsForType(ltype));
158 if (SPEC_LONG(val->type)) {
159 if (SPEC_USIGN(val->type)) {
160 v=SPEC_CVAL(val->type).v_ulong;
162 v=SPEC_CVAL(val->type).v_long;
165 if (SPEC_USIGN(val->type)) {
166 v=SPEC_CVAL(val->type).v_uint;
168 v=SPEC_CVAL(val->type).v_int;
174 // this could be a good idea
175 if (options.pedantic)
179 if (SPEC_NOUN(ltype)==FLOAT) {
184 if (!SPEC_USIGN(val->type) && v<0) {
186 if (SPEC_USIGN(ltype) && (pedantic>1)) {
192 // if very pedantic: "char c=200" is not allowed
193 if (pedantic>1 && !SPEC_USIGN(ltype)) {
194 max = max/2 + negative;
201 #if 0 // temporary disabled, leaving the warning as a reminder
203 sprintf (message, "for %s %s in %s",
204 SPEC_USIGN(ltype) ? "unsigned" : "signed",
205 nounName(ltype), msg);
206 werror (W_CONST_RANGE, message);
214 /*-----------------------------------------------------------------*/
215 /* operandName - returns the name of the operand */
216 /*-----------------------------------------------------------------*/
218 printOperand (operand * op, FILE * file)
235 opetype = getSpec (operandType (op));
236 if (SPEC_NOUN (opetype) == V_FLOAT)
237 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
239 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
240 printTypeChain (operandType (op), file);
247 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%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}" , */
248 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
250 OP_LIVEFROM (op), OP_LIVETO (op),
251 OP_SYMBOL (op)->stack,
252 op->isaddr, OP_SYMBOL (op)->isreqv,
253 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
254 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
258 printTypeChain (operandType (op), file);
259 if (SPIL_LOC (op) && IS_ITEMP (op))
260 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
265 /* if assigned to registers */
266 if (OP_SYMBOL (op)->nRegs)
268 if (OP_SYMBOL (op)->isspilt)
270 if (!OP_SYMBOL (op)->remat)
271 if (OP_SYMBOL (op)->usl.spillLoc)
272 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
273 OP_SYMBOL (op)->usl.spillLoc->rname :
274 OP_SYMBOL (op)->usl.spillLoc->name));
276 fprintf (file, "[err]");
278 fprintf (file, "[remat]");
284 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
285 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
290 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
291 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
292 /* if assigned to registers */
293 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
297 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
298 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
299 OP_SYMBOL (op)->regs[i]->name :
308 printTypeChain (op->operand.typeOperand, file);
314 fprintf (file, "\n");
319 /*-----------------------------------------------------------------*/
320 /* print functions */
321 /*-----------------------------------------------------------------*/
322 PRINTFUNC (picGetValueAtAddr)
325 printOperand (IC_RESULT (ic), of);
328 printOperand (IC_LEFT (ic), of);
334 PRINTFUNC (picSetValueAtAddr)
338 printOperand (IC_LEFT (ic), of);
339 fprintf (of, "] = ");
340 printOperand (IC_RIGHT (ic), of);
344 PRINTFUNC (picAddrOf)
347 printOperand (IC_RESULT (ic), of);
348 if (IS_ITEMP (IC_LEFT (ic)))
351 fprintf (of, " = &[");
352 printOperand (IC_LEFT (ic), of);
355 if (IS_ITEMP (IC_LEFT (ic)))
356 fprintf (of, " offsetAdd ");
359 printOperand (IC_RIGHT (ic), of);
361 if (IS_ITEMP (IC_LEFT (ic)))
367 PRINTFUNC (picJumpTable)
372 fprintf (of, "%s\t", s);
373 printOperand (IC_JTCOND (ic), of);
375 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
376 sym = setNextItem (IC_JTLABELS (ic)))
377 fprintf (of, "\t\t\t%s\n", sym->name);
380 PRINTFUNC (picGeneric)
383 printOperand (IC_RESULT (ic), of);
385 printOperand (IC_LEFT (ic), of);
386 fprintf (of, " %s ", s);
387 printOperand (IC_RIGHT (ic), of);
391 PRINTFUNC (picGenericOne)
396 printOperand (IC_RESULT (ic), of);
402 fprintf (of, "%s ", s);
403 printOperand (IC_LEFT (ic), of);
406 if (!IC_RESULT (ic) && !IC_LEFT (ic))
409 if (ic->op == SEND || ic->op == RECEIVE) {
410 fprintf(of,"{argreg = %d}",ic->argreg);
418 printOperand (IC_RESULT (ic), of);
420 printOperand (IC_LEFT (ic), of);
421 printOperand (IC_RIGHT (ic), of);
426 PRINTFUNC (picAssign)
430 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
433 printOperand (IC_RESULT (ic), of);
435 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
438 fprintf (of, " %s ", s);
439 printOperand (IC_RIGHT (ic), of);
446 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
452 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
459 printOperand (IC_COND (ic), of);
462 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
465 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
467 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
471 PRINTFUNC (picInline)
473 fprintf (of, "%s", IC_INLINE (ic));
476 PRINTFUNC (picReceive)
478 printOperand (IC_RESULT (ic), of);
479 fprintf (of, " = %s ", s);
480 printOperand (IC_LEFT (ic), of);
484 /*-----------------------------------------------------------------*/
485 /* piCode - prints one iCode */
486 /*-----------------------------------------------------------------*/
488 piCode (void *item, FILE * of)
496 icTab = getTableEntry (ic->op);
497 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
498 ic->filename, ic->lineno,
499 ic->seq, ic->key, ic->depth, ic->supportRtn);
500 icTab->iCodePrint (of, ic, icTab->printName);
506 printiCChain(ic,stdout);
508 /*-----------------------------------------------------------------*/
509 /* printiCChain - prints intermediate code for humans */
510 /*-----------------------------------------------------------------*/
512 printiCChain (iCode * icChain, FILE * of)
519 for (loop = icChain; loop; loop = loop->next)
521 if ((icTab = getTableEntry (loop->op)))
523 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
524 loop->filename, loop->lineno,
525 loop->seq, loop->key, loop->depth, loop->supportRtn);
527 icTab->iCodePrint (of, loop, icTab->printName);
533 /*-----------------------------------------------------------------*/
534 /* newOperand - allocate, init & return a new iCode */
535 /*-----------------------------------------------------------------*/
541 op = Safe_alloc ( sizeof (operand));
547 /*-----------------------------------------------------------------*/
548 /* newiCode - create and return a new iCode entry initialised */
549 /*-----------------------------------------------------------------*/
551 newiCode (int op, operand * left, operand * right)
555 ic = Safe_alloc ( sizeof (iCode));
558 ic->filename = filename;
560 ic->level = scopeLevel;
562 ic->key = iCodeKey++;
564 IC_RIGHT (ic) = right;
569 /*-----------------------------------------------------------------*/
570 /* newiCode for conditional statements */
571 /*-----------------------------------------------------------------*/
573 newiCodeCondition (operand * condition,
579 if (IS_VOID(operandType(condition))) {
580 werror(E_VOID_VALUE_USED);
583 ic = newiCode (IFX, NULL, NULL);
584 IC_COND (ic) = condition;
585 IC_TRUE (ic) = trueLabel;
586 IC_FALSE (ic) = falseLabel;
590 /*-----------------------------------------------------------------*/
591 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
592 /*-----------------------------------------------------------------*/
594 newiCodeLabelGoto (int op, symbol * label)
598 ic = newiCode (op, NULL, NULL);
600 ic->argLabel.label = label;
602 IC_RIGHT (ic) = NULL;
603 IC_RESULT (ic) = NULL;
607 /*-----------------------------------------------------------------*/
608 /* newiTemp - allocate & return a newItemp Variable */
609 /*-----------------------------------------------------------------*/
616 sprintf (buffer, "%s", s);
618 sprintf (buffer, "iTemp%d", iTempNum++);
619 itmp = newSymbol (buffer, 1);
620 strcpy (itmp->rname, itmp->name);
626 /*-----------------------------------------------------------------*/
627 /* newiTempLabel - creates a temp variable label */
628 /*-----------------------------------------------------------------*/
630 newiTempLabel (char *s)
634 /* check if this alredy exists */
635 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
639 itmplbl = newSymbol (s, 1);
642 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
643 itmplbl = newSymbol (buffer, 1);
648 itmplbl->key = labelKey++;
649 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
653 /*-----------------------------------------------------------------*/
654 /* newiTempPreheaderLabel - creates a new preheader label */
655 /*-----------------------------------------------------------------*/
657 newiTempPreheaderLabel ()
661 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
662 itmplbl = newSymbol (buffer, 1);
666 itmplbl->key = labelKey++;
667 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
672 /*-----------------------------------------------------------------*/
673 /* initiCode - initialises some iCode related stuff */
674 /*-----------------------------------------------------------------*/
681 /*-----------------------------------------------------------------*/
682 /* copyiCode - make a copy of the iCode given */
683 /*-----------------------------------------------------------------*/
685 copyiCode (iCode * ic)
687 iCode *nic = newiCode (ic->op, NULL, NULL);
689 nic->lineno = ic->lineno;
690 nic->filename = ic->filename;
691 nic->block = ic->block;
692 nic->level = ic->level;
693 nic->parmBytes = ic->parmBytes;
695 /* deal with the special cases first */
699 IC_COND (nic) = operandFromOperand (IC_COND (ic));
700 IC_TRUE (nic) = IC_TRUE (ic);
701 IC_FALSE (nic) = IC_FALSE (ic);
705 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
706 IC_JTLABELS (nic) = IC_JTLABELS (ic);
711 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
712 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
716 IC_INLINE (nic) = IC_INLINE (ic);
720 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
724 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
725 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
726 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
732 /*-----------------------------------------------------------------*/
733 /* getTableEntry - gets the table entry for the given operator */
734 /*-----------------------------------------------------------------*/
736 getTableEntry (int oper)
740 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
741 if (oper == codeTable[i].icode)
742 return &codeTable[i];
747 /*-----------------------------------------------------------------*/
748 /* newiTempOperand - new intermediate temp operand */
749 /*-----------------------------------------------------------------*/
751 newiTempOperand (sym_link * type, char throwType)
754 operand *op = newOperand ();
758 itmp = newiTemp (NULL);
760 etype = getSpec (type);
762 if (IS_LITERAL (etype))
765 /* copy the type information */
767 itmp->etype = getSpec (itmp->type = (throwType ? type :
768 copyLinkChain (type)));
769 if (IS_LITERAL (itmp->etype))
771 SPEC_SCLS (itmp->etype) = S_REGISTER;
772 SPEC_OCLS (itmp->etype) = reg;
775 op->operand.symOperand = itmp;
776 op->key = itmp->key = ++operandKey;
780 /*-----------------------------------------------------------------*/
781 /* operandType - returns the type chain for an operand */
782 /*-----------------------------------------------------------------*/
784 operandType (operand * op)
786 /* depending on type of operand */
791 return op->operand.valOperand->type;
794 return op->operand.symOperand->type;
797 return op->operand.typeOperand;
799 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
800 " operand type not known ");
801 assert (0); /* should never come here */
802 /* Just to keep the compiler happy */
803 return (sym_link *) 0;
807 /*-----------------------------------------------------------------*/
808 /* isParamterToCall - will return 1 if op is a parameter to args */
809 /*-----------------------------------------------------------------*/
811 isParameterToCall (value * args, operand * op)
818 isSymbolEqual (op->operand.symOperand, tval->sym))
825 /*-----------------------------------------------------------------*/
826 /* isOperandGlobal - return 1 if operand is a global variable */
827 /*-----------------------------------------------------------------*/
829 isOperandGlobal (operand * op)
837 if (op->type == SYMBOL &&
838 (op->operand.symOperand->level == 0 ||
839 IS_STATIC (op->operand.symOperand->etype) ||
840 IS_EXTERN (op->operand.symOperand->etype))
847 /*-----------------------------------------------------------------*/
848 /* isOperandVolatile - return 1 if the operand is volatile */
849 /*-----------------------------------------------------------------*/
851 isOperandVolatile (operand * op, bool chkTemp)
856 if (IS_ITEMP (op) && !chkTemp)
859 opetype = getSpec (optype = operandType (op));
861 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
864 if (IS_VOLATILE (opetype))
869 /*-----------------------------------------------------------------*/
870 /* isOperandLiteral - returns 1 if an operand contains a literal */
871 /*-----------------------------------------------------------------*/
873 isOperandLiteral (operand * op)
880 opetype = getSpec (operandType (op));
882 if (IS_LITERAL (opetype))
888 /*-----------------------------------------------------------------*/
889 /* isOperandInFarSpace - will return true if operand is in farSpace */
890 /*-----------------------------------------------------------------*/
892 isOperandInFarSpace (operand * op)
902 if (!IS_TRUE_SYMOP (op))
905 etype = SPIL_LOC (op)->etype;
911 etype = getSpec (operandType (op));
913 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
916 /*------------------------------------------------------------------*/
917 /* isOperandInDirSpace - will return true if operand is in dirSpace */
918 /*------------------------------------------------------------------*/
920 isOperandInDirSpace (operand * op)
930 if (!IS_TRUE_SYMOP (op))
933 etype = SPIL_LOC (op)->etype;
939 etype = getSpec (operandType (op));
941 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
944 /*--------------------------------------------------------------------*/
945 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
946 /*--------------------------------------------------------------------*/
948 isOperandInCodeSpace (operand * op)
958 etype = getSpec (operandType (op));
960 if (!IS_TRUE_SYMOP (op))
963 etype = SPIL_LOC (op)->etype;
969 etype = getSpec (operandType (op));
971 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
974 /*-----------------------------------------------------------------*/
975 /* isOperandOnStack - will return true if operand is on stack */
976 /*-----------------------------------------------------------------*/
978 isOperandOnStack (operand * op)
988 etype = getSpec (operandType (op));
989 if (IN_STACK (etype) ||
990 OP_SYMBOL(op)->onStack ||
991 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
997 /*-----------------------------------------------------------------*/
998 /* operandLitValue - literal value of an operand */
999 /*-----------------------------------------------------------------*/
1001 operandLitValue (operand * op)
1003 assert (isOperandLiteral (op));
1005 return floatFromVal (op->operand.valOperand);
1008 /*-----------------------------------------------------------------*/
1009 /* getBuiltInParms - returns parameters to a builtin functions */
1010 /*-----------------------------------------------------------------*/
1011 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1016 /* builtin functions uses only SEND for parameters */
1017 while (ic->op != CALL) {
1018 assert(ic->op == SEND && ic->builtinSEND);
1019 ic->generated = 1; /* mark the icode as generated */
1020 parms[*pcount] = IC_LEFT(ic);
1026 /* make sure this is a builtin function call */
1027 assert(IS_SYMOP(IC_LEFT(ic)));
1028 ftype = operandType(IC_LEFT(ic));
1029 assert(IFFUNC_ISBUILTIN(ftype));
1033 /*-----------------------------------------------------------------*/
1034 /* operandOperation - perforoms operations on operands */
1035 /*-----------------------------------------------------------------*/
1037 operandOperation (operand * left, operand * right,
1038 int op, sym_link * type)
1040 sym_link *let , *ret=NULL;
1041 operand *retval = (operand *) 0;
1043 assert (isOperandLiteral (left));
1044 let = getSpec(operandType(left));
1046 assert (isOperandLiteral (right));
1047 ret = getSpec(operandType(left));
1053 retval = operandFromValue (valCastLiteral (type,
1054 operandLitValue (left) +
1055 operandLitValue (right)));
1058 retval = operandFromValue (valCastLiteral (type,
1059 operandLitValue (left) -
1060 operandLitValue (right)));
1063 retval = operandFromValue (valCastLiteral (type,
1064 operandLitValue (left) *
1065 operandLitValue (right)));
1068 if ((unsigned long) operandLitValue (right) == 0)
1070 werror (E_DIVIDE_BY_ZERO);
1075 retval = operandFromValue (valCastLiteral (type,
1076 operandLitValue (left) /
1077 operandLitValue (right)));
1080 if ((unsigned long) operandLitValue (right) == 0) {
1081 werror (E_DIVIDE_BY_ZERO);
1085 retval = operandFromLit ((SPEC_USIGN(let) ?
1086 (unsigned long) operandLitValue (left) :
1087 (long) operandLitValue (left)) %
1089 (unsigned long) operandLitValue (right) :
1090 (long) operandLitValue (right)));
1094 retval = operandFromLit ((SPEC_USIGN(let) ?
1095 (unsigned long) operandLitValue (left) :
1096 (long) operandLitValue (left)) <<
1098 (unsigned long) operandLitValue (right) :
1099 (long) operandLitValue (right)));
1102 double lval = operandLitValue(left), rval = operandLitValue(right);
1104 switch ((SPEC_USIGN(let) ? 2 : 0) + (SPEC_USIGN(ret) ? 1 : 0))
1106 case 0: // left=unsigned right=unsigned
1107 res=(unsigned long)lval >> (unsigned long)rval;
1109 case 1: // left=unsigned right=signed
1110 res=(unsigned long)lval >> (signed long)rval;
1112 case 2: // left=signed right=unsigned
1113 res=(signed long)lval >> (unsigned long)rval;
1115 case 3: // left=signed right=signed
1116 res=(signed long)lval >> (signed long)rval;
1119 retval = operandFromLit (res);
1123 retval = operandFromLit (operandLitValue (left) ==
1124 operandLitValue (right));
1127 retval = operandFromLit (operandLitValue (left) <
1128 operandLitValue (right));
1131 retval = operandFromLit (operandLitValue (left) <=
1132 operandLitValue (right));
1135 retval = operandFromLit (operandLitValue (left) !=
1136 operandLitValue (right));
1139 retval = operandFromLit (operandLitValue (left) >
1140 operandLitValue (right));
1143 retval = operandFromLit (operandLitValue (left) >=
1144 operandLitValue (right));
1147 retval = operandFromLit ((long)operandLitValue(left) &
1148 (long)operandLitValue(right));
1151 retval = operandFromLit ((long)operandLitValue (left) |
1152 (long)operandLitValue (right));
1155 retval = operandFromLit ((long)operandLitValue (left) ^
1156 (long)operandLitValue (right));
1159 retval = operandFromLit (operandLitValue (left) &&
1160 operandLitValue (right));
1163 retval = operandFromLit (operandLitValue (left) ||
1164 operandLitValue (right));
1168 long i = (long) operandLitValue (left);
1170 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1176 long i = (long) operandLitValue (left);
1178 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1184 retval = operandFromLit (-1 * operandLitValue (left));
1188 retval = operandFromLit (~((long) operandLitValue (left)));
1192 retval = operandFromLit (!operandLitValue (left));
1196 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1197 " operandOperation invalid operator ");
1205 /*-----------------------------------------------------------------*/
1206 /* isOperandEqual - compares two operand & return 1 if they r = */
1207 /*-----------------------------------------------------------------*/
1209 isOperandEqual (operand * left, operand * right)
1211 /* if the pointers are equal then they are equal */
1215 /* if either of them null then false */
1216 if (!left || !right)
1219 if (left->type != right->type)
1222 if (IS_SYMOP (left) && IS_SYMOP (right))
1223 return left->key == right->key;
1225 /* if types are the same */
1229 return isSymbolEqual (left->operand.symOperand,
1230 right->operand.symOperand);
1232 return (floatFromVal (left->operand.valOperand) ==
1233 floatFromVal (right->operand.valOperand));
1235 if (compareType (left->operand.typeOperand,
1236 right->operand.typeOperand) == 1)
1243 /*-------------------------------------------------------------------*/
1244 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1245 /*-------------------------------------------------------------------*/
1247 isiCodeEqual (iCode * left, iCode * right)
1249 /* if the same pointer */
1253 /* if either of them null */
1254 if (!left || !right)
1257 /* if operand are the same */
1258 if (left->op == right->op)
1261 /* compare all the elements depending on type */
1262 if (left->op != IFX)
1264 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1266 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1272 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1274 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1276 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1285 /*-----------------------------------------------------------------*/
1286 /* newiTempFromOp - create a temp Operand with same attributes */
1287 /*-----------------------------------------------------------------*/
1289 newiTempFromOp (operand * op)
1299 nop = newiTempOperand (operandType (op), TRUE);
1300 nop->isaddr = op->isaddr;
1301 nop->isvolatile = op->isvolatile;
1302 nop->isGlobal = op->isGlobal;
1303 nop->isLiteral = op->isLiteral;
1304 nop->usesDefs = op->usesDefs;
1305 nop->isParm = op->isParm;
1309 /*-----------------------------------------------------------------*/
1310 /* operand from operand - creates an operand holder for the type */
1311 /*-----------------------------------------------------------------*/
1313 operandFromOperand (operand * op)
1319 nop = newOperand ();
1320 nop->type = op->type;
1321 nop->isaddr = op->isaddr;
1323 nop->isvolatile = op->isvolatile;
1324 nop->isGlobal = op->isGlobal;
1325 nop->isLiteral = op->isLiteral;
1326 nop->usesDefs = op->usesDefs;
1327 nop->isParm = op->isParm;
1332 nop->operand.symOperand = op->operand.symOperand;
1335 nop->operand.valOperand = op->operand.valOperand;
1338 nop->operand.typeOperand = op->operand.typeOperand;
1345 /*-----------------------------------------------------------------*/
1346 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1347 /*-----------------------------------------------------------------*/
1349 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1351 operand *nop = operandFromOperand (op);
1353 if (nop->type == SYMBOL)
1355 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1356 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1362 /*-----------------------------------------------------------------*/
1363 /* operandFromSymbol - creates an operand from a symbol */
1364 /*-----------------------------------------------------------------*/
1366 operandFromSymbol (symbol * sym)
1371 /* if the symbol's type is a literal */
1372 /* then it is an enumerator type */
1373 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1374 return operandFromValue (valFromType (sym->etype));
1377 sym->key = ++operandKey;
1379 /* if this an implicit variable, means struct/union */
1380 /* member so just return it */
1381 if (sym->implicit || IS_FUNC (sym->type))
1385 op->operand.symOperand = sym;
1387 op->isvolatile = isOperandVolatile (op, TRUE);
1388 op->isGlobal = isOperandGlobal (op);
1392 /* under the following conditions create a
1393 register equivalent for a local symbol */
1394 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1395 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1396 (!(options.model == MODEL_FLAT24)) ) &&
1397 options.stackAuto == 0)
1400 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1401 !IS_FUNC (sym->type) && /* not a function */
1402 !sym->_isparm && /* not a parameter */
1403 sym->level && /* is a local variable */
1404 !sym->addrtaken && /* whose address has not been taken */
1405 !sym->reqv && /* does not already have a reg equivalence */
1406 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1407 !IS_STATIC (sym->etype) && /* and not declared static */
1408 !sym->islbl && /* not a label */
1409 ok && /* farspace check */
1410 !IS_BITVAR (sym->etype) /* not a bit variable */
1414 /* we will use it after all optimizations
1415 and before liveRange calculation */
1416 sym->reqv = newiTempOperand (sym->type, 0);
1417 sym->reqv->key = sym->key;
1418 OP_SYMBOL (sym->reqv)->key = sym->key;
1419 OP_SYMBOL (sym->reqv)->isreqv = 1;
1420 OP_SYMBOL (sym->reqv)->islocal = 1;
1421 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1422 SPIL_LOC (sym->reqv) = sym;
1425 if (!IS_AGGREGATE (sym->type))
1429 op->operand.symOperand = sym;
1432 op->isvolatile = isOperandVolatile (op, TRUE);
1433 op->isGlobal = isOperandGlobal (op);
1434 op->isPtr = IS_PTR (operandType (op));
1435 op->isParm = sym->_isparm;
1440 /* itemp = &[_symbol] */
1442 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1443 IC_LEFT (ic)->type = SYMBOL;
1444 IC_LEFT (ic)->operand.symOperand = sym;
1445 IC_LEFT (ic)->key = sym->key;
1446 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1447 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1448 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1451 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1452 if (IS_ARRAY (sym->type))
1454 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1455 IC_RESULT (ic)->isaddr = 0;
1458 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1462 return IC_RESULT (ic);
1465 /*-----------------------------------------------------------------*/
1466 /* operandFromValue - creates an operand from value */
1467 /*-----------------------------------------------------------------*/
1469 operandFromValue (value * val)
1473 /* if this is a symbol then do the symbol thing */
1475 return operandFromSymbol (val->sym);
1477 /* this is not a symbol */
1480 op->operand.valOperand = val;
1481 op->isLiteral = isOperandLiteral (op);
1485 /*-----------------------------------------------------------------*/
1486 /* operandFromLink - operand from typeChain */
1487 /*-----------------------------------------------------------------*/
1489 operandFromLink (sym_link * type)
1493 /* operand from sym_link */
1499 op->operand.typeOperand = copyLinkChain (type);
1503 /*-----------------------------------------------------------------*/
1504 /* operandFromLit - makes an operand from a literal value */
1505 /*-----------------------------------------------------------------*/
1507 operandFromLit (double i)
1509 return operandFromValue (valueFromLit (i));
1512 /*-----------------------------------------------------------------*/
1513 /* operandFromAst - creates an operand from an ast */
1514 /*-----------------------------------------------------------------*/
1516 operandFromAst (ast * tree,int lvl)
1522 /* depending on type do */
1526 return ast2iCode (tree,lvl+1);
1530 return operandFromValue (tree->opval.val);
1534 return operandFromLink (tree->opval.lnk);
1538 /* Just to keep the comiler happy */
1539 return (operand *) 0;
1542 /*-----------------------------------------------------------------*/
1543 /* setOperandType - sets the operand's type to the given type */
1544 /*-----------------------------------------------------------------*/
1546 setOperandType (operand * op, sym_link * type)
1548 /* depending on the type of operand */
1553 op->operand.valOperand->etype =
1554 getSpec (op->operand.valOperand->type =
1555 copyLinkChain (type));
1559 if (op->operand.symOperand->isitmp)
1560 op->operand.symOperand->etype =
1561 getSpec (op->operand.symOperand->type =
1562 copyLinkChain (type));
1564 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1565 "attempt to modify type of source");
1569 op->operand.typeOperand = copyLinkChain (type);
1574 /*-----------------------------------------------------------------*/
1575 /* Get size in byte of ptr need to access an array */
1576 /*-----------------------------------------------------------------*/
1578 getArraySizePtr (operand * op)
1580 sym_link *ltype = operandType(op);
1584 int size = getSize(ltype);
1585 return(IS_GENPTR(ltype)?(size-1):size);
1590 sym_link *letype = getSpec(ltype);
1591 switch (PTR_TYPE (SPEC_OCLS (letype)))
1603 return (GPTRSIZE-1);
1612 /*-----------------------------------------------------------------*/
1613 /* perform "usual unary conversions" */
1614 /*-----------------------------------------------------------------*/
1616 usualUnaryConversions (operand * op)
1618 if (IS_INTEGRAL (operandType (op)))
1620 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1623 return geniCodeCast (INTTYPE, op, TRUE);
1629 /*-----------------------------------------------------------------*/
1630 /* perform "usual binary conversions" */
1631 /*-----------------------------------------------------------------*/
1633 usualBinaryConversions (operand ** op1, operand ** op2)
1636 sym_link *rtype = operandType (*op2);
1637 sym_link *ltype = operandType (*op1);
1639 ctype = computeType (ltype, rtype);
1641 *op1 = geniCodeCast (ctype, *op1, TRUE);
1642 *op2 = geniCodeCast (ctype, *op2, TRUE);
1647 /*-----------------------------------------------------------------*/
1648 /* geniCodeValueAtAddress - generate intermeditate code for value */
1650 /*-----------------------------------------------------------------*/
1652 geniCodeRValue (operand * op, bool force)
1655 sym_link *type = operandType (op);
1656 sym_link *etype = getSpec (type);
1658 /* if this is an array & already */
1659 /* an address then return this */
1660 if (IS_AGGREGATE (type) ||
1661 (IS_PTR (type) && !force && !op->isaddr))
1662 return operandFromOperand (op);
1664 /* if this is not an address then must be */
1665 /* rvalue already so return this one */
1669 /* if this is not a temp symbol then */
1670 if (!IS_ITEMP (op) &&
1672 !IN_FARSPACE (SPEC_OCLS (etype)))
1674 op = operandFromOperand (op);
1679 if (IS_SPEC (type) &&
1680 IS_TRUE_SYMOP (op) &&
1681 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1682 (options.model == MODEL_FLAT24) ))
1684 op = operandFromOperand (op);
1689 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1690 if (IS_PTR (type) && op->isaddr && force)
1693 type = copyLinkChain (type);
1695 IC_RESULT (ic) = newiTempOperand (type, 1);
1696 IC_RESULT (ic)->isaddr = 0;
1698 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1702 return IC_RESULT (ic);
1705 /*-----------------------------------------------------------------*/
1706 /* geniCodeCast - changes the value from one type to another */
1707 /*-----------------------------------------------------------------*/
1709 geniCodeCast (sym_link * type, operand * op, bool implicit)
1713 sym_link *opetype = getSpec (optype = operandType (op));
1717 /* one of them has size zero then error */
1718 if (IS_VOID (optype))
1720 werror (E_CAST_ZERO);
1724 /* if the operand is already the desired type then do nothing */
1725 if (compareType (type, optype) == 1)
1728 /* if this is a literal then just change the type & return */
1729 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1730 return operandFromValue (valCastLiteral (type,
1731 operandLitValue (op)));
1733 /* if casting to/from pointers, do some checking */
1734 if (IS_PTR(type)) { // to a pointer
1735 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1736 if (IS_INTEGRAL(optype)) {
1737 // maybe this is NULL, than it's ok.
1738 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1739 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1740 // no way to set the storage
1741 if (IS_LITERAL(optype)) {
1742 werror(E_LITERAL_GENERIC);
1745 werror(E_NONPTR2_GENPTR);
1748 } else if (implicit) {
1749 werror(W_INTEGRAL2PTR_NOCAST);
1754 // shouldn't do that with float, array or structure unless to void
1755 if (!IS_VOID(getSpec(type)) &&
1756 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1757 werror(E_INCOMPAT_TYPES);
1761 } else { // from a pointer to a pointer
1762 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1763 // if not a pointer to a function
1764 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1765 if (implicit) { // if not to generic, they have to match
1766 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1767 werror(E_INCOMPAT_PTYPES);
1774 } else { // to a non pointer
1775 if (IS_PTR(optype)) { // from a pointer
1776 if (implicit) { // sneaky
1777 if (IS_INTEGRAL(type)) {
1778 werror(W_PTR2INTEGRAL_NOCAST);
1780 } else { // shouldn't do that with float, array or structure
1781 werror(E_INCOMPAT_TYPES);
1788 printFromToType (optype, type);
1791 /* if they are the same size create an assignment */
1792 if (getSize (type) == getSize (optype) &&
1793 !IS_BITFIELD (type) &&
1795 !IS_FLOAT (optype) &&
1796 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1797 (!IS_SPEC (type) && !IS_SPEC (optype))))
1800 ic = newiCode ('=', NULL, op);
1801 IC_RESULT (ic) = newiTempOperand (type, 0);
1802 SPIL_LOC (IC_RESULT (ic)) =
1803 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1804 IC_RESULT (ic)->isaddr = 0;
1808 ic = newiCode (CAST, operandFromLink (type),
1809 geniCodeRValue (op, FALSE));
1811 IC_RESULT (ic) = newiTempOperand (type, 0);
1814 /* preserve the storage class & output class */
1815 /* of the original variable */
1816 restype = getSpec (operandType (IC_RESULT (ic)));
1817 if (!IS_LITERAL(opetype))
1818 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1819 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1822 return IC_RESULT (ic);
1825 /*-----------------------------------------------------------------*/
1826 /* geniCodeLabel - will create a Label */
1827 /*-----------------------------------------------------------------*/
1829 geniCodeLabel (symbol * label)
1833 ic = newiCodeLabelGoto (LABEL, label);
1837 /*-----------------------------------------------------------------*/
1838 /* geniCodeGoto - will create a Goto */
1839 /*-----------------------------------------------------------------*/
1841 geniCodeGoto (symbol * label)
1845 ic = newiCodeLabelGoto (GOTO, label);
1849 /*-----------------------------------------------------------------*/
1850 /* geniCodeMultiply - gen intermediate code for multiplication */
1851 /*-----------------------------------------------------------------*/
1853 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1860 /* if they are both literal then we know the result */
1861 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1862 return operandFromValue (valMult (left->operand.valOperand,
1863 right->operand.valOperand));
1865 if (IS_LITERAL(retype)) {
1866 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1869 resType = usualBinaryConversions (&left, &right);
1871 rtype = operandType (right);
1872 retype = getSpec (rtype);
1873 ltype = operandType (left);
1874 letype = getSpec (ltype);
1878 SPEC_NOUN(getSpec(resType))=V_INT;
1881 /* if the right is a literal & power of 2 */
1882 /* then make it a left shift */
1883 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1884 efficient in most cases than 2 bytes result = 2 bytes << literal
1885 if port has 1 byte muldiv */
1886 if (p2 && !IS_FLOAT (letype) &&
1887 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1888 (port->support.muldiv == 1)))
1890 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1892 /* LEFT_OP need same size for left and result, */
1893 left = geniCodeCast (resType, left, TRUE);
1894 ltype = operandType (left);
1896 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1900 ic = newiCode ('*', left, right); /* normal multiplication */
1901 /* if the size left or right > 1 then support routine */
1902 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1906 IC_RESULT (ic) = newiTempOperand (resType, 1);
1909 return IC_RESULT (ic);
1912 /*-----------------------------------------------------------------*/
1913 /* geniCodeDivision - gen intermediate code for division */
1914 /*-----------------------------------------------------------------*/
1916 geniCodeDivision (operand * left, operand * right)
1921 sym_link *rtype = operandType (right);
1922 sym_link *retype = getSpec (rtype);
1923 sym_link *ltype = operandType (left);
1924 sym_link *letype = getSpec (ltype);
1926 resType = usualBinaryConversions (&left, &right);
1928 /* if the right is a literal & power of 2
1929 and left is unsigned then make it a
1931 if (IS_LITERAL (retype) &&
1932 !IS_FLOAT (letype) &&
1933 SPEC_USIGN(letype) &&
1934 (p2 = powof2 ((unsigned long)
1935 floatFromVal (right->operand.valOperand)))) {
1936 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1940 ic = newiCode ('/', left, right); /* normal division */
1941 /* if the size left or right > 1 then support routine */
1942 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1945 IC_RESULT (ic) = newiTempOperand (resType, 0);
1948 return IC_RESULT (ic);
1950 /*-----------------------------------------------------------------*/
1951 /* geniCodeModulus - gen intermediate code for modulus */
1952 /*-----------------------------------------------------------------*/
1954 geniCodeModulus (operand * left, operand * right)
1960 /* if they are both literal then we know the result */
1961 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1962 return operandFromValue (valMod (left->operand.valOperand,
1963 right->operand.valOperand));
1965 resType = usualBinaryConversions (&left, &right);
1967 /* now they are the same size */
1968 ic = newiCode ('%', left, right);
1970 /* if the size left or right > 1 then support routine */
1971 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1973 IC_RESULT (ic) = newiTempOperand (resType, 0);
1976 return IC_RESULT (ic);
1979 /*-----------------------------------------------------------------*/
1980 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1981 /*-----------------------------------------------------------------*/
1983 geniCodePtrPtrSubtract (operand * left, operand * right)
1989 /* if they are both literals then */
1990 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1992 result = operandFromValue (valMinus (left->operand.valOperand,
1993 right->operand.valOperand));
1997 ic = newiCode ('-', left, right);
1999 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2003 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2007 // should we really do this? is this ANSI?
2008 return geniCodeDivision (result,
2009 operandFromLit (getSize (ltype->next)));
2012 /*-----------------------------------------------------------------*/
2013 /* geniCodeSubtract - generates code for subtraction */
2014 /*-----------------------------------------------------------------*/
2016 geniCodeSubtract (operand * left, operand * right)
2023 /* if they both pointers then */
2024 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2025 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2026 return geniCodePtrPtrSubtract (left, right);
2028 /* if they are both literal then we know the result */
2029 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2030 && left->isLiteral && right->isLiteral)
2031 return operandFromValue (valMinus (left->operand.valOperand,
2032 right->operand.valOperand));
2034 /* if left is an array or pointer */
2035 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2037 isarray = left->isaddr;
2038 right = geniCodeMultiply (right,
2039 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2040 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2043 { /* make them the same size */
2044 resType = usualBinaryConversions (&left, &right);
2047 ic = newiCode ('-', left, right);
2049 IC_RESULT (ic) = newiTempOperand (resType, 1);
2050 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2052 /* if left or right is a float */
2053 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2057 return IC_RESULT (ic);
2060 /*-----------------------------------------------------------------*/
2061 /* geniCodeAdd - generates iCode for addition */
2062 /*-----------------------------------------------------------------*/
2064 geniCodeAdd (operand * left, operand * right, int lvl)
2073 /* if left is an array then array access */
2074 if (IS_ARRAY (ltype))
2075 return geniCodeArray (left, right,lvl);
2078 /* if the right side is LITERAL zero */
2079 /* return the left side */
2080 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2083 /* if left is literal zero return right */
2084 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2087 /* if left is a pointer then size */
2088 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2090 isarray = left->isaddr;
2091 // there is no need to multiply with 1
2092 if (getSize(ltype->next)!=1) {
2093 size = operandFromLit (getSize (ltype->next));
2094 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2096 resType = copyLinkChain (ltype);
2099 { // make them the same size
2100 resType = usualBinaryConversions (&left, &right);
2103 /* if they are both literals then we know */
2104 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2105 && left->isLiteral && right->isLiteral)
2106 return operandFromValue (valPlus (valFromType (letype),
2107 valFromType (retype)));
2109 ic = newiCode ('+', left, right);
2111 IC_RESULT (ic) = newiTempOperand (resType, 1);
2112 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2114 /* if left or right is a float then support
2116 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2121 return IC_RESULT (ic);
2125 /*-----------------------------------------------------------------*/
2126 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2127 /*-----------------------------------------------------------------*/
2129 aggrToPtr (sym_link * type, bool force)
2135 if (IS_PTR (type) && !force)
2138 etype = getSpec (type);
2142 /* if the output class is generic */
2143 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2144 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2146 /* if the variable was declared a constant */
2147 /* then the pointer points to a constant */
2148 if (IS_CONSTANT (etype))
2149 DCL_PTR_CONST (ptype) = 1;
2151 /* the variable was volatile then pointer to volatile */
2152 if (IS_VOLATILE (etype))
2153 DCL_PTR_VOLATILE (ptype) = 1;
2157 /*-----------------------------------------------------------------*/
2158 /* geniCodeArray2Ptr - array to pointer */
2159 /*-----------------------------------------------------------------*/
2161 geniCodeArray2Ptr (operand * op)
2163 sym_link *optype = operandType (op);
2164 sym_link *opetype = getSpec (optype);
2166 /* set the pointer depending on the storage class */
2167 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2168 DCL_PTR_CONST (optype) = port->mem.code_ro;
2171 /* if the variable was declared a constant */
2172 /* then the pointer points to a constant */
2173 if (IS_CONSTANT (opetype))
2174 DCL_PTR_CONST (optype) = 1;
2176 /* the variable was volatile then pointer to volatile */
2177 if (IS_VOLATILE (opetype))
2178 DCL_PTR_VOLATILE (optype) = 1;
2184 /*-----------------------------------------------------------------*/
2185 /* geniCodeArray - array access */
2186 /*-----------------------------------------------------------------*/
2188 geniCodeArray (operand * left, operand * right,int lvl)
2191 sym_link *ltype = operandType (left);
2195 if (IS_PTR (ltype->next) && left->isaddr)
2197 left = geniCodeRValue (left, FALSE);
2199 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2202 right = geniCodeMultiply (right,
2203 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2205 /* we can check for limits here */
2206 if (isOperandLiteral (right) &&
2209 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2211 werror (E_ARRAY_BOUND);
2212 right = operandFromLit (0);
2215 ic = newiCode ('+', left, right);
2217 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2218 !IS_AGGREGATE (ltype->next) &&
2219 !IS_PTR (ltype->next))
2220 ? ltype : ltype->next), 0);
2222 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2224 return IC_RESULT (ic);
2227 /*-----------------------------------------------------------------*/
2228 /* geniCodeStruct - generates intermediate code for structres */
2229 /*-----------------------------------------------------------------*/
2231 geniCodeStruct (operand * left, operand * right, bool islval)
2234 sym_link *type = operandType (left);
2235 sym_link *etype = getSpec (type);
2237 symbol *element = getStructElement (SPEC_STRUCT (etype),
2238 right->operand.symOperand);
2240 /* add the offset */
2241 ic = newiCode ('+', left, operandFromLit (element->offset));
2243 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2245 /* preserve the storage & output class of the struct */
2246 /* as well as the volatile attribute */
2247 retype = getSpec (operandType (IC_RESULT (ic)));
2248 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2249 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2250 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2252 if (IS_PTR (element->type))
2253 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2255 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2259 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2262 /*-----------------------------------------------------------------*/
2263 /* geniCodePostInc - generate int code for Post increment */
2264 /*-----------------------------------------------------------------*/
2266 geniCodePostInc (operand * op)
2270 sym_link *optype = operandType (op);
2272 operand *rv = (IS_ITEMP (op) ?
2273 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2275 sym_link *rvtype = operandType (rv);
2278 /* if this is not an address we have trouble */
2281 werror (E_LVALUE_REQUIRED, "++");
2285 rOp = newiTempOperand (rvtype, 0);
2286 OP_SYMBOL(rOp)->noSpilLoc = 1;
2289 OP_SYMBOL(rv)->noSpilLoc = 1;
2291 geniCodeAssign (rOp, rv, 0);
2293 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2294 if (IS_FLOAT (rvtype))
2295 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2297 ic = newiCode ('+', rv, operandFromLit (size));
2299 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2302 geniCodeAssign (op, result, 0);
2308 /*-----------------------------------------------------------------*/
2309 /* geniCodePreInc - generate code for preIncrement */
2310 /*-----------------------------------------------------------------*/
2312 geniCodePreInc (operand * op)
2315 sym_link *optype = operandType (op);
2316 operand *rop = (IS_ITEMP (op) ?
2317 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2319 sym_link *roptype = operandType (rop);
2325 werror (E_LVALUE_REQUIRED, "++");
2330 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2331 if (IS_FLOAT (roptype))
2332 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2334 ic = newiCode ('+', rop, operandFromLit (size));
2335 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2339 return geniCodeAssign (op, result, 0);
2342 /*-----------------------------------------------------------------*/
2343 /* geniCodePostDec - generates code for Post decrement */
2344 /*-----------------------------------------------------------------*/
2346 geniCodePostDec (operand * op)
2350 sym_link *optype = operandType (op);
2352 operand *rv = (IS_ITEMP (op) ?
2353 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2355 sym_link *rvtype = operandType (rv);
2358 /* if this is not an address we have trouble */
2361 werror (E_LVALUE_REQUIRED, "--");
2365 rOp = newiTempOperand (rvtype, 0);
2366 OP_SYMBOL(rOp)->noSpilLoc = 1;
2369 OP_SYMBOL(rv)->noSpilLoc = 1;
2371 geniCodeAssign (rOp, rv, 0);
2373 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2374 if (IS_FLOAT (rvtype))
2375 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2377 ic = newiCode ('-', rv, operandFromLit (size));
2379 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2382 geniCodeAssign (op, result, 0);
2388 /*-----------------------------------------------------------------*/
2389 /* geniCodePreDec - generate code for pre decrement */
2390 /*-----------------------------------------------------------------*/
2392 geniCodePreDec (operand * op)
2395 sym_link *optype = operandType (op);
2396 operand *rop = (IS_ITEMP (op) ?
2397 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2399 sym_link *roptype = operandType (rop);
2405 werror (E_LVALUE_REQUIRED, "--");
2410 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2411 if (IS_FLOAT (roptype))
2412 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2414 ic = newiCode ('-', rop, operandFromLit (size));
2415 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2419 return geniCodeAssign (op, result, 0);
2423 /*-----------------------------------------------------------------*/
2424 /* geniCodeBitwise - gen int code for bitWise operators */
2425 /*-----------------------------------------------------------------*/
2427 geniCodeBitwise (operand * left, operand * right,
2428 int oper, sym_link * resType)
2432 left = geniCodeCast (resType, left, TRUE);
2433 right = geniCodeCast (resType, right, TRUE);
2435 ic = newiCode (oper, left, right);
2436 IC_RESULT (ic) = newiTempOperand (resType, 0);
2439 return IC_RESULT (ic);
2442 /*-----------------------------------------------------------------*/
2443 /* geniCodeAddressOf - gens icode for '&' address of operator */
2444 /*-----------------------------------------------------------------*/
2446 geniCodeAddressOf (operand * op)
2450 sym_link *optype = operandType (op);
2451 sym_link *opetype = getSpec (optype);
2453 /* lvalue check already done in decorateType */
2454 /* this must be a lvalue */
2455 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2456 /* werror (E_LVALUE_REQUIRED,"&"); */
2461 p->class = DECLARATOR;
2463 /* set the pointer depending on the storage class */
2464 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2465 DCL_PTR_CONST (p) = port->mem.code_ro;
2467 /* make sure we preserve the const & volatile */
2468 if (IS_CONSTANT (opetype))
2469 DCL_PTR_CONST (p) = 1;
2471 if (IS_VOLATILE (opetype))
2472 DCL_PTR_VOLATILE (p) = 1;
2474 p->next = copyLinkChain (optype);
2476 /* if already a temp */
2479 setOperandType (op, p);
2484 /* other wise make this of the type coming in */
2485 ic = newiCode (ADDRESS_OF, op, NULL);
2486 IC_RESULT (ic) = newiTempOperand (p, 1);
2487 IC_RESULT (ic)->isaddr = 0;
2489 return IC_RESULT (ic);
2491 /*-----------------------------------------------------------------*/
2492 /* setOClass - sets the output class depending on the pointer type */
2493 /*-----------------------------------------------------------------*/
2495 setOClass (sym_link * ptr, sym_link * spec)
2497 switch (DCL_TYPE (ptr))
2500 SPEC_OCLS (spec) = data;
2504 SPEC_OCLS (spec) = generic;
2508 SPEC_OCLS (spec) = xdata;
2512 SPEC_OCLS (spec) = code;
2516 SPEC_OCLS (spec) = idata;
2520 SPEC_OCLS (spec) = xstack;
2524 SPEC_OCLS (spec) = eeprom;
2533 /*-----------------------------------------------------------------*/
2534 /* geniCodeDerefPtr - dereference pointer with '*' */
2535 /*-----------------------------------------------------------------*/
2537 geniCodeDerefPtr (operand * op,int lvl)
2539 sym_link *rtype, *retype;
2540 sym_link *optype = operandType (op);
2542 /* if this is a pointer then generate the rvalue */
2543 if (IS_PTR (optype))
2545 if (IS_TRUE_SYMOP (op))
2548 op = geniCodeRValue (op, TRUE);
2551 op = geniCodeRValue (op, TRUE);
2554 /* now get rid of the pointer part */
2555 if (isLvaluereq(lvl) && IS_ITEMP (op))
2557 retype = getSpec (rtype = copyLinkChain (optype));
2561 retype = getSpec (rtype = copyLinkChain (optype->next));
2564 /* if this is a pointer then outputclass needs 2b updated */
2565 if (IS_PTR (optype))
2566 setOClass (optype, retype);
2568 op->isGptr = IS_GENPTR (optype);
2570 /* if the pointer was declared as a constant */
2571 /* then we cannot allow assignment to the derefed */
2572 if (IS_PTR_CONST (optype))
2573 SPEC_CONST (retype) = 1;
2575 op->isaddr = (IS_PTR (rtype) ||
2576 IS_STRUCT (rtype) ||
2581 if (!isLvaluereq(lvl))
2582 op = geniCodeRValue (op, TRUE);
2584 setOperandType (op, rtype);
2589 /*-----------------------------------------------------------------*/
2590 /* geniCodeUnaryMinus - does a unary minus of the operand */
2591 /*-----------------------------------------------------------------*/
2593 geniCodeUnaryMinus (operand * op)
2596 sym_link *optype = operandType (op);
2598 if (IS_LITERAL (optype))
2599 return operandFromLit (-floatFromVal (op->operand.valOperand));
2601 ic = newiCode (UNARYMINUS, op, NULL);
2602 IC_RESULT (ic) = newiTempOperand (optype, 0);
2604 return IC_RESULT (ic);
2607 /*-----------------------------------------------------------------*/
2608 /* geniCodeLeftShift - gen i code for left shift */
2609 /*-----------------------------------------------------------------*/
2611 geniCodeLeftShift (operand * left, operand * right)
2615 ic = newiCode (LEFT_OP, left, right);
2616 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2618 return IC_RESULT (ic);
2621 /*-----------------------------------------------------------------*/
2622 /* geniCodeRightShift - gen i code for right shift */
2623 /*-----------------------------------------------------------------*/
2625 geniCodeRightShift (operand * left, operand * right)
2629 ic = newiCode (RIGHT_OP, left, right);
2630 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2632 return IC_RESULT (ic);
2635 /*-----------------------------------------------------------------*/
2636 /* geniCodeLogic- logic code */
2637 /*-----------------------------------------------------------------*/
2639 geniCodeLogic (operand * left, operand * right, int op)
2643 sym_link *rtype = operandType (right);
2644 sym_link *ltype = operandType (left);
2646 /* left is integral type and right is literal then
2647 check if the literal value is within bounds */
2648 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2650 checkConstantRange(ltype,
2651 OP_VALUE(right), "compare operation", 1);
2654 ctype = usualBinaryConversions (&left, &right);
2656 ic = newiCode (op, left, right);
2657 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2659 /* if comparing float
2660 and not a '==' || '!=' || '&&' || '||' (these
2662 if (IS_FLOAT(ctype) &&
2670 return IC_RESULT (ic);
2673 /*-----------------------------------------------------------------*/
2674 /* geniCodeUnary - for a a generic unary operation */
2675 /*-----------------------------------------------------------------*/
2677 geniCodeUnary (operand * op, int oper)
2679 iCode *ic = newiCode (oper, op, NULL);
2681 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2683 return IC_RESULT (ic);
2686 /*-----------------------------------------------------------------*/
2687 /* geniCodeConditional - geniCode for '?' ':' operation */
2688 /*-----------------------------------------------------------------*/
2690 geniCodeConditional (ast * tree,int lvl)
2693 symbol *falseLabel = newiTempLabel (NULL);
2694 symbol *exitLabel = newiTempLabel (NULL);
2695 operand *cond = ast2iCode (tree->left,lvl+1);
2696 operand *true, *false, *result;
2698 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2702 true = ast2iCode (tree->right->left,lvl+1);
2704 /* move the value to a new Operand */
2705 result = newiTempOperand (tree->right->ftype, 0);
2706 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2708 /* generate an unconditional goto */
2709 geniCodeGoto (exitLabel);
2711 /* now for the right side */
2712 geniCodeLabel (falseLabel);
2714 false = ast2iCode (tree->right->right,lvl+1);
2715 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2717 /* create the exit label */
2718 geniCodeLabel (exitLabel);
2723 /*-----------------------------------------------------------------*/
2724 /* geniCodeAssign - generate code for assignment */
2725 /*-----------------------------------------------------------------*/
2727 geniCodeAssign (operand * left, operand * right, int nosupdate)
2730 sym_link *ltype = operandType (left);
2731 sym_link *rtype = operandType (right);
2733 if (!left->isaddr && !IS_ITEMP (left))
2735 werror (E_LVALUE_REQUIRED, "assignment");
2739 /* left is integral type and right is literal then
2740 check if the literal value is within bounds */
2741 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2743 checkConstantRange(ltype,
2744 OP_VALUE(right), "= operation", 0);
2747 /* if the left & right type don't exactly match */
2748 /* if pointer set then make sure the check is
2749 done with the type & not the pointer */
2750 /* then cast rights type to left */
2752 /* first check the type for pointer assignement */
2753 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2754 compareType (ltype, rtype) <= 0)
2756 if (compareType (ltype->next, rtype) < 0)
2757 right = geniCodeCast (ltype->next, right, TRUE);
2759 else if (compareType (ltype, rtype) < 0)
2760 right = geniCodeCast (ltype, right, TRUE);
2762 /* if left is a true symbol & ! volatile
2763 create an assignment to temporary for
2764 the right & then assign this temporary
2765 to the symbol this is SSA . isn't it simple
2766 and folks have published mountains of paper on it */
2767 if (IS_TRUE_SYMOP (left) &&
2768 !isOperandVolatile (left, FALSE) &&
2769 isOperandGlobal (left))
2773 if (IS_TRUE_SYMOP (right))
2774 sym = OP_SYMBOL (right);
2775 ic = newiCode ('=', NULL, right);
2776 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2777 SPIL_LOC (right) = sym;
2781 ic = newiCode ('=', NULL, right);
2782 IC_RESULT (ic) = left;
2785 /* if left isgptr flag is set then support
2786 routine will be required */
2790 ic->nosupdate = nosupdate;
2794 /*-----------------------------------------------------------------*/
2795 /* geniCodeSEParms - generate code for side effecting fcalls */
2796 /*-----------------------------------------------------------------*/
2798 geniCodeSEParms (ast * parms,int lvl)
2803 if (parms->type == EX_OP && parms->opval.op == PARAM)
2805 geniCodeSEParms (parms->left,lvl);
2806 geniCodeSEParms (parms->right,lvl);
2810 /* hack don't like this but too lazy to think of
2812 if (IS_ADDRESS_OF_OP (parms))
2813 parms->left->lvalue = 1;
2815 if (IS_CAST_OP (parms) &&
2816 IS_PTR (parms->ftype) &&
2817 IS_ADDRESS_OF_OP (parms->right))
2818 parms->right->left->lvalue = 1;
2820 parms->opval.oprnd =
2821 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2823 parms->type = EX_OPERAND;
2824 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2825 SPEC_ARGREG(parms->ftype);
2828 /*-----------------------------------------------------------------*/
2829 /* geniCodeParms - generates parameters */
2830 /*-----------------------------------------------------------------*/
2832 geniCodeParms (ast * parms, value *argVals, int *stack,
2833 sym_link * fetype, symbol * func,int lvl)
2841 if (argVals==NULL) {
2843 argVals=FUNC_ARGS(func->type);
2846 /* if this is a param node then do the left & right */
2847 if (parms->type == EX_OP && parms->opval.op == PARAM)
2849 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2850 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2854 /* get the parameter value */
2855 if (parms->type == EX_OPERAND)
2856 pval = parms->opval.oprnd;
2859 /* maybe this else should go away ?? */
2860 /* hack don't like this but too lazy to think of
2862 if (IS_ADDRESS_OF_OP (parms))
2863 parms->left->lvalue = 1;
2865 if (IS_CAST_OP (parms) &&
2866 IS_PTR (parms->ftype) &&
2867 IS_ADDRESS_OF_OP (parms->right))
2868 parms->right->left->lvalue = 1;
2870 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2873 /* if register parm then make it a send */
2874 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2875 IFFUNC_ISBUILTIN(func->type))
2877 ic = newiCode (SEND, pval, NULL);
2878 ic->argreg = SPEC_ARGREG(parms->etype);
2879 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2884 /* now decide whether to push or assign */
2885 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2889 operand *top = operandFromSymbol (argVals->sym);
2890 /* clear useDef and other bitVectors */
2891 OP_USES_SET ((top), OP_DEFS_SET ((top), OP_SYMBOL(top)->clashes = NULL));
2892 geniCodeAssign (top, pval, 1);
2896 sym_link *p = operandType (pval);
2898 ic = newiCode (IPUSH, pval, NULL);
2900 /* update the stack adjustment */
2901 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2906 argVals=argVals->next;
2910 /*-----------------------------------------------------------------*/
2911 /* geniCodeCall - generates temp code for calling */
2912 /*-----------------------------------------------------------------*/
2914 geniCodeCall (operand * left, ast * parms,int lvl)
2918 sym_link *type, *etype;
2921 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2922 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2923 werror (E_FUNCTION_EXPECTED);
2927 /* take care of parameters with side-effecting
2928 function calls in them, this is required to take care
2929 of overlaying function parameters */
2930 geniCodeSEParms (parms,lvl);
2932 /* first the parameters */
2933 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2935 /* now call : if symbol then pcall */
2936 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
2937 ic = newiCode (PCALL, left, NULL);
2939 ic = newiCode (CALL, left, NULL);
2942 type = copyLinkChain (operandType (left)->next);
2943 etype = getSpec (type);
2944 SPEC_EXTR (etype) = 0;
2945 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2949 /* stack adjustment after call */
2950 ic->parmBytes = stack;
2955 /*-----------------------------------------------------------------*/
2956 /* geniCodeReceive - generate intermediate code for "receive" */
2957 /*-----------------------------------------------------------------*/
2959 geniCodeReceive (value * args)
2961 /* for all arguments that are passed in registers */
2965 if (IS_REGPARM (args->etype))
2967 operand *opr = operandFromValue (args);
2969 symbol *sym = OP_SYMBOL (opr);
2972 /* we will use it after all optimizations
2973 and before liveRange calculation */
2974 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2977 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2978 options.stackAuto == 0 &&
2979 (!(options.model == MODEL_FLAT24)) )
2984 opl = newiTempOperand (args->type, 0);
2986 sym->reqv->key = sym->key;
2987 OP_SYMBOL (sym->reqv)->key = sym->key;
2988 OP_SYMBOL (sym->reqv)->isreqv = 1;
2989 OP_SYMBOL (sym->reqv)->islocal = 0;
2990 SPIL_LOC (sym->reqv) = sym;
2994 ic = newiCode (RECEIVE, NULL, NULL);
2995 ic->argreg = SPEC_ARGREG(args->etype);
2997 currFunc->recvSize = getSize (sym->type);
3000 IC_RESULT (ic) = opr;
3008 /*-----------------------------------------------------------------*/
3009 /* geniCodeFunctionBody - create the function body */
3010 /*-----------------------------------------------------------------*/
3012 geniCodeFunctionBody (ast * tree,int lvl)
3019 /* reset the auto generation */
3025 func = ast2iCode (tree->left,lvl+1);
3026 fetype = getSpec (operandType (func));
3028 savelineno = lineno;
3029 lineno = OP_SYMBOL (func)->lineDef;
3030 /* create an entry label */
3031 geniCodeLabel (entryLabel);
3032 lineno = savelineno;
3034 /* create a proc icode */
3035 ic = newiCode (FUNCTION, func, NULL);
3036 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3040 /* for all parameters that are passed
3041 on registers add a "receive" */
3042 geniCodeReceive (tree->values.args);
3044 /* generate code for the body */
3045 ast2iCode (tree->right,lvl+1);
3047 /* create a label for return */
3048 geniCodeLabel (returnLabel);
3050 /* now generate the end proc */
3051 ic = newiCode (ENDFUNCTION, func, NULL);
3056 /*-----------------------------------------------------------------*/
3057 /* geniCodeReturn - gen icode for 'return' statement */
3058 /*-----------------------------------------------------------------*/
3060 geniCodeReturn (operand * op)
3064 /* if the operand is present force an rvalue */
3066 op = geniCodeRValue (op, FALSE);
3068 ic = newiCode (RETURN, op, NULL);
3072 /*-----------------------------------------------------------------*/
3073 /* geniCodeIfx - generates code for extended if statement */
3074 /*-----------------------------------------------------------------*/
3076 geniCodeIfx (ast * tree,int lvl)
3079 operand *condition = ast2iCode (tree->left,lvl+1);
3082 /* if condition is null then exit */
3086 condition = geniCodeRValue (condition, FALSE);
3088 cetype = getSpec (operandType (condition));
3089 /* if the condition is a literal */
3090 if (IS_LITERAL (cetype))
3092 if (floatFromVal (condition->operand.valOperand))
3094 if (tree->trueLabel)
3095 geniCodeGoto (tree->trueLabel);
3101 if (tree->falseLabel)
3102 geniCodeGoto (tree->falseLabel);
3109 if (tree->trueLabel)
3111 ic = newiCodeCondition (condition,
3116 if (tree->falseLabel)
3117 geniCodeGoto (tree->falseLabel);
3121 ic = newiCodeCondition (condition,
3128 ast2iCode (tree->right,lvl+1);
3131 /*-----------------------------------------------------------------*/
3132 /* geniCodeJumpTable - tries to create a jump table for switch */
3133 /*-----------------------------------------------------------------*/
3135 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3137 int min = 0, max = 0, t, cnt = 0;
3144 if (!tree || !caseVals)
3147 /* the criteria for creating a jump table is */
3148 /* all integer numbers between the maximum & minimum must */
3149 /* be present , the maximum value should not exceed 255 */
3150 min = max = (int) floatFromVal (vch = caseVals);
3151 sprintf (buffer, "_case_%d_%d",
3152 tree->values.switchVals.swNum,
3154 addSet (&labels, newiTempLabel (buffer));
3156 /* if there is only one case value then no need */
3157 if (!(vch = vch->next))
3162 if (((t = (int) floatFromVal (vch)) - max) != 1)
3164 sprintf (buffer, "_case_%d_%d",
3165 tree->values.switchVals.swNum,
3167 addSet (&labels, newiTempLabel (buffer));
3173 /* if the number of case statements <= 2 then */
3174 /* it is not economical to create the jump table */
3175 /* since two compares are needed for boundary conditions */
3176 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3179 if (tree->values.switchVals.swDefault)
3180 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3182 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3184 falseLabel = newiTempLabel (buffer);
3186 /* so we can create a jumptable */
3187 /* first we rule out the boundary conditions */
3188 /* if only optimization says so */
3189 if (!optimize.noJTabBoundary)
3191 sym_link *cetype = getSpec (operandType (cond));
3192 /* no need to check the lower bound if
3193 the condition is unsigned & minimum value is zero */
3194 if (!(min == 0 && SPEC_USIGN (cetype)))
3196 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3197 ic = newiCodeCondition (boundary, falseLabel, NULL);
3201 /* now for upper bounds */
3202 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3203 ic = newiCodeCondition (boundary, falseLabel, NULL);
3207 /* if the min is not zero then we no make it zero */
3210 cond = geniCodeSubtract (cond, operandFromLit (min));
3211 setOperandType (cond, UCHARTYPE);
3214 /* now create the jumptable */
3215 ic = newiCode (JUMPTABLE, NULL, NULL);
3216 IC_JTCOND (ic) = cond;
3217 IC_JTLABELS (ic) = labels;
3222 /*-----------------------------------------------------------------*/
3223 /* geniCodeSwitch - changes a switch to a if statement */
3224 /*-----------------------------------------------------------------*/
3226 geniCodeSwitch (ast * tree,int lvl)
3229 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3230 value *caseVals = tree->values.switchVals.swVals;
3231 symbol *trueLabel, *falseLabel;
3233 /* if we can make this a jump table */
3234 if (geniCodeJumpTable (cond, caseVals, tree))
3235 goto jumpTable; /* no need for the comparison */
3237 /* for the cases defined do */
3241 operand *compare = geniCodeLogic (cond,
3242 operandFromValue (caseVals),
3245 sprintf (buffer, "_case_%d_%d",
3246 tree->values.switchVals.swNum,
3247 (int) floatFromVal (caseVals));
3248 trueLabel = newiTempLabel (buffer);
3250 ic = newiCodeCondition (compare, trueLabel, NULL);
3252 caseVals = caseVals->next;
3257 /* if default is present then goto break else break */
3258 if (tree->values.switchVals.swDefault)
3259 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3261 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3263 falseLabel = newiTempLabel (buffer);
3264 geniCodeGoto (falseLabel);
3267 ast2iCode (tree->right,lvl+1);
3270 /*-----------------------------------------------------------------*/
3271 /* geniCodeInline - intermediate code for inline assembler */
3272 /*-----------------------------------------------------------------*/
3274 geniCodeInline (ast * tree)
3278 ic = newiCode (INLINEASM, NULL, NULL);
3279 IC_INLINE (ic) = tree->values.inlineasm;
3283 /*-----------------------------------------------------------------*/
3284 /* geniCodeArrayInit - intermediate code for array initializer */
3285 /*-----------------------------------------------------------------*/
3287 geniCodeArrayInit (ast * tree, operand *array)
3291 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3292 ic = newiCode (ARRAYINIT, array, NULL);
3293 IC_ARRAYILIST (ic) = tree->values.constlist;
3295 operand *left=newOperand(), *right=newOperand();
3296 left->type=right->type=SYMBOL;
3297 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3298 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3299 ic = newiCode (ARRAYINIT, left, right);
3304 /*-----------------------------------------------------------------*/
3305 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3306 /* particular case. Ie : assigning or dereferencing array or ptr */
3307 /*-----------------------------------------------------------------*/
3308 set * lvaluereqSet = NULL;
3309 typedef struct lvalItem
3316 /*-----------------------------------------------------------------*/
3317 /* addLvaluereq - add a flag for lvalreq for current ast level */
3318 /*-----------------------------------------------------------------*/
3319 void addLvaluereq(int lvl)
3321 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3324 addSetHead(&lvaluereqSet,lpItem);
3327 /*-----------------------------------------------------------------*/
3328 /* delLvaluereq - del a flag for lvalreq for current ast level */
3329 /*-----------------------------------------------------------------*/
3333 lpItem = getSet(&lvaluereqSet);
3334 if(lpItem) Safe_free(lpItem);
3336 /*-----------------------------------------------------------------*/
3337 /* clearLvaluereq - clear lvalreq flag */
3338 /*-----------------------------------------------------------------*/
3339 void clearLvaluereq()
3342 lpItem = peekSet(lvaluereqSet);
3343 if(lpItem) lpItem->req = 0;
3345 /*-----------------------------------------------------------------*/
3346 /* getLvaluereq - get the last lvalreq level */
3347 /*-----------------------------------------------------------------*/
3348 int getLvaluereqLvl()
3351 lpItem = peekSet(lvaluereqSet);
3352 if(lpItem) return lpItem->lvl;
3355 /*-----------------------------------------------------------------*/
3356 /* isLvaluereq - is lvalreq valid for this level ? */
3357 /*-----------------------------------------------------------------*/
3358 int isLvaluereq(int lvl)
3361 lpItem = peekSet(lvaluereqSet);
3362 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3366 /*-----------------------------------------------------------------*/
3367 /* ast2iCode - creates an icodeList from an ast */
3368 /*-----------------------------------------------------------------*/
3370 ast2iCode (ast * tree,int lvl)
3372 operand *left = NULL;
3373 operand *right = NULL;
3377 /* set the global variables for filename & line number */
3379 filename = tree->filename;
3381 lineno = tree->lineno;
3383 block = tree->block;
3385 scopeLevel = tree->level;
3387 if (tree->type == EX_VALUE)
3388 return operandFromValue (tree->opval.val);
3390 if (tree->type == EX_LINK)
3391 return operandFromLink (tree->opval.lnk);
3393 /* if we find a nullop */
3394 if (tree->type == EX_OP &&
3395 (tree->opval.op == NULLOP ||
3396 tree->opval.op == BLOCK))
3398 ast2iCode (tree->left,lvl+1);
3399 ast2iCode (tree->right,lvl+1);
3403 /* special cases for not evaluating */
3404 if (tree->opval.op != ':' &&
3405 tree->opval.op != '?' &&
3406 tree->opval.op != CALL &&
3407 tree->opval.op != IFX &&
3408 tree->opval.op != LABEL &&
3409 tree->opval.op != GOTO &&
3410 tree->opval.op != SWITCH &&
3411 tree->opval.op != FUNCTION &&
3412 tree->opval.op != INLINEASM)
3415 if (IS_ASSIGN_OP (tree->opval.op) ||
3416 IS_DEREF_OP (tree) ||
3417 (tree->opval.op == '&' && !tree->right) ||
3418 tree->opval.op == PTR_OP)
3421 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3422 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3425 left = operandFromAst (tree->left,lvl);
3427 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3428 left = geniCodeRValue (left, TRUE);
3432 left = operandFromAst (tree->left,lvl);
3434 if (tree->opval.op == INC_OP ||
3435 tree->opval.op == DEC_OP)
3438 right = operandFromAst (tree->right,lvl);
3443 right = operandFromAst (tree->right,lvl);
3447 /* now depending on the type of operand */
3448 /* this will be a biggy */
3449 switch (tree->opval.op)
3452 case '[': /* array operation */
3454 //sym_link *ltype = operandType (left);
3455 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3456 left = geniCodeRValue (left, FALSE);
3457 right = geniCodeRValue (right, TRUE);
3460 return geniCodeArray (left, right,lvl);
3462 case '.': /* structure dereference */
3463 if (IS_PTR (operandType (left)))
3464 left = geniCodeRValue (left, TRUE);
3466 left = geniCodeRValue (left, FALSE);
3468 return geniCodeStruct (left, right, tree->lvalue);
3470 case PTR_OP: /* structure pointer dereference */
3473 pType = operandType (left);
3474 left = geniCodeRValue (left, TRUE);
3476 setOClass (pType, getSpec (operandType (left)));
3479 return geniCodeStruct (left, right, tree->lvalue);
3481 case INC_OP: /* increment operator */
3483 return geniCodePostInc (left);
3485 return geniCodePreInc (right);
3487 case DEC_OP: /* decrement operator */
3489 return geniCodePostDec (left);
3491 return geniCodePreDec (right);
3493 case '&': /* bitwise and or address of operator */
3495 { /* this is a bitwise operator */
3496 left = geniCodeRValue (left, FALSE);
3497 right = geniCodeRValue (right, FALSE);
3498 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3501 return geniCodeAddressOf (left);
3503 case '|': /* bitwise or & xor */
3505 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3506 geniCodeRValue (right, FALSE),
3511 return geniCodeDivision (geniCodeRValue (left, FALSE),
3512 geniCodeRValue (right, FALSE));
3515 return geniCodeModulus (geniCodeRValue (left, FALSE),
3516 geniCodeRValue (right, FALSE));
3519 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3520 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3522 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3526 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3527 geniCodeRValue (right, FALSE));
3529 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3533 return geniCodeAdd (geniCodeRValue (left, FALSE),
3534 geniCodeRValue (right, FALSE),lvl);
3536 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3539 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3540 geniCodeRValue (right, FALSE));
3543 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3544 geniCodeRValue (right, FALSE));
3546 return geniCodeCast (operandType (left),
3547 geniCodeRValue (right, FALSE), FALSE);
3553 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3557 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3558 setOperandType (op, UCHARTYPE);
3569 return geniCodeLogic (geniCodeRValue (left, FALSE),
3570 geniCodeRValue (right, FALSE),
3573 return geniCodeConditional (tree,lvl);
3576 return operandFromLit (getSize (tree->right->ftype));
3580 sym_link *rtype = operandType (right);
3581 sym_link *ltype = operandType (left);
3582 if (IS_PTR (rtype) && IS_ITEMP (right)
3583 && right->isaddr && compareType (rtype->next, ltype) == 1)
3584 right = geniCodeRValue (right, TRUE);
3586 right = geniCodeRValue (right, FALSE);
3588 geniCodeAssign (left, right, 0);
3593 geniCodeAssign (left,
3594 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3596 geniCodeRValue (right, FALSE),FALSE), 0);
3600 geniCodeAssign (left,
3601 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3603 geniCodeRValue (right, FALSE)), 0);
3606 geniCodeAssign (left,
3607 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3609 geniCodeRValue (right, FALSE)), 0);
3612 sym_link *rtype = operandType (right);
3613 sym_link *ltype = operandType (left);
3614 if (IS_PTR (rtype) && IS_ITEMP (right)
3615 && right->isaddr && compareType (rtype->next, ltype) == 1)
3616 right = geniCodeRValue (right, TRUE);
3618 right = geniCodeRValue (right, FALSE);
3621 return geniCodeAssign (left,
3622 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3628 sym_link *rtype = operandType (right);
3629 sym_link *ltype = operandType (left);
3630 if (IS_PTR (rtype) && IS_ITEMP (right)
3631 && right->isaddr && compareType (rtype->next, ltype) == 1)
3633 right = geniCodeRValue (right, TRUE);
3637 right = geniCodeRValue (right, FALSE);
3640 geniCodeAssign (left,
3641 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3647 geniCodeAssign (left,
3648 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3650 geniCodeRValue (right, FALSE)), 0);
3653 geniCodeAssign (left,
3654 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3656 geniCodeRValue (right, FALSE)), 0);
3659 geniCodeAssign (left,
3660 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3662 geniCodeRValue (right, FALSE),
3664 operandType (left)), 0);
3667 geniCodeAssign (left,
3668 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3670 geniCodeRValue (right, FALSE),
3672 operandType (left)), 0);
3675 geniCodeAssign (left,
3676 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3678 geniCodeRValue (right, FALSE),
3680 operandType (left)), 0);
3682 return geniCodeRValue (right, FALSE);
3685 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3688 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3689 return ast2iCode (tree->right,lvl+1);
3692 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3693 return ast2iCode (tree->right,lvl+1);
3696 geniCodeFunctionBody (tree,lvl);
3700 geniCodeReturn (right);
3704 geniCodeIfx (tree,lvl);
3708 geniCodeSwitch (tree,lvl);
3712 geniCodeInline (tree);
3716 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3723 /*-----------------------------------------------------------------*/
3724 /* reverseICChain - gets from the list and creates a linkedlist */
3725 /*-----------------------------------------------------------------*/
3732 while ((loop = getSet (&iCodeChain)))
3744 /*-----------------------------------------------------------------*/
3745 /* iCodeFromAst - given an ast will convert it to iCode */
3746 /*-----------------------------------------------------------------*/
3748 iCodeFromAst (ast * tree)
3750 returnLabel = newiTempLabel ("_return");
3751 entryLabel = newiTempLabel ("_entry");
3753 return reverseiCChain ();