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 -------------------------------------------------------------------------*/
28 /*-----------------------------------------------------------------*/
29 /* global variables */
31 set *iCodeChain = NULL;
41 symbol *returnLabel; /* function return label */
42 symbol *entryLabel; /* function entry label */
44 #if defined(__BORLANDC__) || defined(_MSC_VER)
45 #define LONG_LONG __int64
47 #define LONG_LONG long long
50 /*-----------------------------------------------------------------*/
51 /* forward definition of some functions */
52 operand *geniCodeDivision (operand *, operand *);
53 operand *geniCodeAssign (operand *, operand *, int);
54 operand *geniCodeArray (operand *, operand *,int);
55 operand *geniCodeArray2Ptr (operand *);
56 operand *geniCodeRValue (operand *, bool);
57 operand *geniCodeDerefPtr (operand *,int);
58 int isLvaluereq(int lvl);
60 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
61 /* forward definition of ic print functions */
62 PRINTFUNC (picGetValueAtAddr);
63 PRINTFUNC (picSetValueAtAddr);
64 PRINTFUNC (picAddrOf);
65 PRINTFUNC (picGeneric);
66 PRINTFUNC (picGenericOne);
68 PRINTFUNC (picAssign);
72 PRINTFUNC (picJumpTable);
73 PRINTFUNC (picInline);
74 PRINTFUNC (picReceive);
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 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
123 /*-----------------------------------------------------------------*/
124 /* checkConstantRange: check a constant against the type */
125 /*-----------------------------------------------------------------*/
127 /* pedantic=0: allmost anything is allowed as long as the absolute
128 value is within the bit range of the type, and -1 is treated as
129 0xf..f for unsigned types (e.g. in assign)
130 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
131 pedantic>1: "char c=200" is not allowed (evaluates to -56)
134 void checkConstantRange(sym_link *ltype, double v, char *msg, int pedantic) {
135 LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype);
136 char message[132]="";
141 // this could be a good idea
142 if (options.pedantic)
146 if (SPEC_NOUN(ltype)==FLOAT) {
153 // if not pedantic: -1 equals to 0xf..f
154 if (SPEC_USIGN(ltype) && (!pedantic ? v!=-1 : 1)) {
160 // if very pedantic: "char c=200" is not allowed
161 if (pedantic>1 && !SPEC_USIGN(ltype)) {
162 max = max/2 + negative;
170 sprintf (message, "for %s %s in %s",
171 SPEC_USIGN(ltype) ? "unsigned" : "signed",
172 nounName(ltype), msg);
173 werror (W_CONST_RANGE, message);
180 /*-----------------------------------------------------------------*/
181 /* operandName - returns the name of the operand */
182 /*-----------------------------------------------------------------*/
184 printOperand (operand * op, FILE * file)
201 opetype = getSpec (operandType (op));
202 if (SPEC_NOUN (opetype) == V_FLOAT)
203 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
205 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
206 printTypeChain (operandType (op), file);
213 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
214 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
216 OP_LIVEFROM (op), OP_LIVETO (op),
217 OP_SYMBOL (op)->stack,
218 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
222 printTypeChain (operandType (op), file);
223 if (SPIL_LOC (op) && IS_ITEMP (op))
224 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
229 /* if assigned to registers */
230 if (OP_SYMBOL (op)->nRegs)
232 if (OP_SYMBOL (op)->isspilt)
234 if (!OP_SYMBOL (op)->remat)
235 if (OP_SYMBOL (op)->usl.spillLoc)
236 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
237 OP_SYMBOL (op)->usl.spillLoc->rname :
238 OP_SYMBOL (op)->usl.spillLoc->name));
240 fprintf (file, "[err]");
242 fprintf (file, "[remat]");
248 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
249 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
254 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
255 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
256 /* if assigned to registers */
257 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
261 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
262 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
263 OP_SYMBOL (op)->regs[i]->name :
272 printTypeChain (op->operand.typeOperand, file);
278 fprintf (file, "\n");
283 /*-----------------------------------------------------------------*/
284 /* print functions */
285 /*-----------------------------------------------------------------*/
286 PRINTFUNC (picGetValueAtAddr)
289 printOperand (IC_RESULT (ic), of);
292 printOperand (IC_LEFT (ic), of);
298 PRINTFUNC (picSetValueAtAddr)
302 printOperand (IC_LEFT (ic), of);
303 fprintf (of, "] = ");
304 printOperand (IC_RIGHT (ic), of);
308 PRINTFUNC (picAddrOf)
311 printOperand (IC_RESULT (ic), of);
312 if (IS_ITEMP (IC_LEFT (ic)))
315 fprintf (of, " = &[");
316 printOperand (IC_LEFT (ic), of);
319 if (IS_ITEMP (IC_LEFT (ic)))
320 fprintf (of, " offsetAdd ");
323 printOperand (IC_RIGHT (ic), of);
325 if (IS_ITEMP (IC_LEFT (ic)))
331 PRINTFUNC (picJumpTable)
336 fprintf (of, "%s\t", s);
337 printOperand (IC_JTCOND (ic), of);
339 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
340 sym = setNextItem (IC_JTLABELS (ic)))
341 fprintf (of, "\t\t\t%s\n", sym->name);
344 PRINTFUNC (picGeneric)
347 printOperand (IC_RESULT (ic), of);
349 printOperand (IC_LEFT (ic), of);
350 fprintf (of, " %s ", s);
351 printOperand (IC_RIGHT (ic), of);
355 PRINTFUNC (picGenericOne)
360 printOperand (IC_RESULT (ic), of);
366 fprintf (of, "%s ", s);
367 printOperand (IC_LEFT (ic), of);
370 if (!IC_RESULT (ic) && !IC_LEFT (ic))
379 printOperand (IC_RESULT (ic), of);
381 printOperand (IC_LEFT (ic), of);
382 printOperand (IC_RIGHT (ic), of);
387 PRINTFUNC (picAssign)
391 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
394 printOperand (IC_RESULT (ic), of);
396 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
399 fprintf (of, " %s ", s);
400 printOperand (IC_RIGHT (ic), of);
407 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
413 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
420 printOperand (IC_COND (ic), of);
423 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
426 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
428 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
432 PRINTFUNC (picInline)
434 fprintf (of, "%s", IC_INLINE (ic));
437 PRINTFUNC (picReceive)
439 printOperand (IC_RESULT (ic), of);
440 fprintf (of, " = %s ", s);
441 printOperand (IC_LEFT (ic), of);
445 /*-----------------------------------------------------------------*/
446 /* piCode - prints one iCode */
447 /*-----------------------------------------------------------------*/
449 piCode (void *item, FILE * of)
457 icTab = getTableEntry (ic->op);
458 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
459 ic->filename, ic->lineno,
460 ic->seq, ic->key, ic->depth, ic->supportRtn);
461 icTab->iCodePrint (of, ic, icTab->printName);
467 printiCChain(ic,stdout);
469 /*-----------------------------------------------------------------*/
470 /* printiCChain - prints intermediate code for humans */
471 /*-----------------------------------------------------------------*/
473 printiCChain (iCode * icChain, FILE * of)
480 for (loop = icChain; loop; loop = loop->next)
482 if ((icTab = getTableEntry (loop->op)))
484 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
485 loop->filename, loop->lineno,
486 loop->seq, loop->key, loop->depth, loop->supportRtn);
488 icTab->iCodePrint (of, loop, icTab->printName);
494 /*-----------------------------------------------------------------*/
495 /* newOperand - allocate, init & return a new iCode */
496 /*-----------------------------------------------------------------*/
502 op = Safe_calloc (1, sizeof (operand));
508 /*-----------------------------------------------------------------*/
509 /* newiCode - create and return a new iCode entry initialised */
510 /*-----------------------------------------------------------------*/
512 newiCode (int op, operand * left, operand * right)
516 ic = Safe_calloc (1, sizeof (iCode));
519 ic->filename = filename;
521 ic->level = scopeLevel;
523 ic->key = iCodeKey++;
525 IC_RIGHT (ic) = right;
530 /*-----------------------------------------------------------------*/
531 /* newiCode for conditional statements */
532 /*-----------------------------------------------------------------*/
534 newiCodeCondition (operand * condition,
540 if (IS_VOID(OP_SYMBOL(condition)->type)) {
541 werror(E_VOID_VALUE_USED);
544 ic = newiCode (IFX, NULL, NULL);
545 IC_COND (ic) = condition;
546 IC_TRUE (ic) = trueLabel;
547 IC_FALSE (ic) = falseLabel;
551 /*-----------------------------------------------------------------*/
552 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
553 /*-----------------------------------------------------------------*/
555 newiCodeLabelGoto (int op, symbol * label)
559 ic = newiCode (op, NULL, NULL);
561 ic->argLabel.label = label;
563 IC_RIGHT (ic) = NULL;
564 IC_RESULT (ic) = NULL;
568 /*-----------------------------------------------------------------*/
569 /* newiTemp - allocate & return a newItemp Variable */
570 /*-----------------------------------------------------------------*/
577 sprintf (buffer, "%s", s);
579 sprintf (buffer, "iTemp%d", iTempNum++);
580 itmp = newSymbol (buffer, 1);
581 strcpy (itmp->rname, itmp->name);
587 /*-----------------------------------------------------------------*/
588 /* newiTempLabel - creates a temp variable label */
589 /*-----------------------------------------------------------------*/
591 newiTempLabel (char *s)
595 /* check if this alredy exists */
596 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
600 itmplbl = newSymbol (s, 1);
603 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
604 itmplbl = newSymbol (buffer, 1);
609 itmplbl->key = labelKey++;
610 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
614 /*-----------------------------------------------------------------*/
615 /* newiTempPreheaderLabel - creates a new preheader label */
616 /*-----------------------------------------------------------------*/
618 newiTempPreheaderLabel ()
622 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
623 itmplbl = newSymbol (buffer, 1);
627 itmplbl->key = labelKey++;
628 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
633 /*-----------------------------------------------------------------*/
634 /* initiCode - initialises some iCode related stuff */
635 /*-----------------------------------------------------------------*/
642 /*-----------------------------------------------------------------*/
643 /* copyiCode - make a copy of the iCode given */
644 /*-----------------------------------------------------------------*/
646 copyiCode (iCode * ic)
648 iCode *nic = newiCode (ic->op, NULL, NULL);
650 nic->lineno = ic->lineno;
651 nic->filename = ic->filename;
652 nic->block = ic->block;
653 nic->level = ic->level;
654 nic->parmBytes = ic->parmBytes;
656 /* deal with the special cases first */
660 IC_COND (nic) = operandFromOperand (IC_COND (ic));
661 IC_TRUE (nic) = IC_TRUE (ic);
662 IC_FALSE (nic) = IC_FALSE (ic);
666 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
667 IC_JTLABELS (nic) = IC_JTLABELS (ic);
672 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
673 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
674 IC_ARGS (nic) = IC_ARGS (ic);
678 IC_INLINE (nic) = IC_INLINE (ic);
682 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
686 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
687 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
688 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
694 /*-----------------------------------------------------------------*/
695 /* getTableEntry - gets the table entry for the given operator */
696 /*-----------------------------------------------------------------*/
698 getTableEntry (int oper)
702 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
703 if (oper == codeTable[i].icode)
704 return &codeTable[i];
709 /*-----------------------------------------------------------------*/
710 /* newiTempOperand - new intermediate temp operand */
711 /*-----------------------------------------------------------------*/
713 newiTempOperand (sym_link * type, char throwType)
716 operand *op = newOperand ();
720 itmp = newiTemp (NULL);
722 etype = getSpec (type);
724 if (IS_LITERAL (etype))
727 /* copy the type information */
729 itmp->etype = getSpec (itmp->type = (throwType ? type :
730 copyLinkChain (type)));
731 if (IS_LITERAL (itmp->etype))
733 SPEC_SCLS (itmp->etype) = S_REGISTER;
734 SPEC_OCLS (itmp->etype) = reg;
737 op->operand.symOperand = itmp;
738 op->key = itmp->key = ++operandKey;
742 /*-----------------------------------------------------------------*/
743 /* operandType - returns the type chain for an operand */
744 /*-----------------------------------------------------------------*/
746 operandType (operand * op)
748 /* depending on type of operand */
753 return op->operand.valOperand->type;
756 return op->operand.symOperand->type;
759 return op->operand.typeOperand;
761 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
762 " operand type not known ");
763 assert (0); /* should never come here */
764 /* Just to keep the compiler happy */
765 return (sym_link *) 0;
769 /*-----------------------------------------------------------------*/
770 /* isParamterToCall - will return 1 if op is a parameter to args */
771 /*-----------------------------------------------------------------*/
773 isParameterToCall (value * args, operand * op)
780 isSymbolEqual (op->operand.symOperand, tval->sym))
787 /*-----------------------------------------------------------------*/
788 /* isOperandGlobal - return 1 if operand is a global variable */
789 /*-----------------------------------------------------------------*/
791 isOperandGlobal (operand * op)
799 if (op->type == SYMBOL &&
800 (op->operand.symOperand->level == 0 ||
801 IS_STATIC (op->operand.symOperand->etype) ||
802 IS_EXTERN (op->operand.symOperand->etype))
809 /*-----------------------------------------------------------------*/
810 /* isOperandVolatile - return 1 if the operand is volatile */
811 /*-----------------------------------------------------------------*/
813 isOperandVolatile (operand * op, bool chkTemp)
818 if (IS_ITEMP (op) && !chkTemp)
821 opetype = getSpec (optype = operandType (op));
823 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
826 if (IS_VOLATILE (opetype))
831 /*-----------------------------------------------------------------*/
832 /* isOperandLiteral - returns 1 if an operand contains a literal */
833 /*-----------------------------------------------------------------*/
835 isOperandLiteral (operand * op)
842 opetype = getSpec (operandType (op));
844 if (IS_LITERAL (opetype))
849 /*-----------------------------------------------------------------*/
850 /* isOperandInFarSpace - will return true if operand is in farSpace */
851 /*-----------------------------------------------------------------*/
853 isOperandInFarSpace (operand * op)
863 if (!IS_TRUE_SYMOP (op))
866 etype = SPIL_LOC (op)->etype;
872 etype = getSpec (operandType (op));
874 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
877 /*-----------------------------------------------------------------*/
878 /* isOperandOnStack - will return true if operand is on stack */
879 /*-----------------------------------------------------------------*/
881 isOperandOnStack (operand * op)
891 etype = getSpec (operandType (op));
893 return ((IN_STACK (etype)) ? TRUE : FALSE);
896 /*-----------------------------------------------------------------*/
897 /* operandLitValue - literal value of an operand */
898 /*-----------------------------------------------------------------*/
900 operandLitValue (operand * op)
902 assert (isOperandLiteral (op));
904 return floatFromVal (op->operand.valOperand);
907 /*-----------------------------------------------------------------*/
908 /* operandOperation - perforoms operations on operands */
909 /*-----------------------------------------------------------------*/
911 operandOperation (operand * left, operand * right,
912 int op, sym_link * type)
914 sym_link *let , *ret=NULL;
915 operand *retval = (operand *) 0;
917 assert (isOperandLiteral (left));
918 let = getSpec(operandType(left));
920 assert (isOperandLiteral (right));
921 ret = getSpec(operandType(left));
927 retval = operandFromValue (valCastLiteral (type,
928 operandLitValue (left) +
929 operandLitValue (right)));
932 retval = operandFromValue (valCastLiteral (type,
933 operandLitValue (left) -
934 operandLitValue (right)));
937 retval = operandFromValue (valCastLiteral (type,
938 operandLitValue (left) *
939 operandLitValue (right)));
942 if ((unsigned long) operandLitValue (right) == 0)
944 werror (E_DIVIDE_BY_ZERO);
949 retval = operandFromValue (valCastLiteral (type,
950 operandLitValue (left) /
951 operandLitValue (right)));
954 if ((unsigned long) operandLitValue (right) == 0) {
955 werror (E_DIVIDE_BY_ZERO);
959 retval = operandFromLit ((SPEC_USIGN(let) ?
960 (unsigned long) operandLitValue (left) :
961 (long) operandLitValue (left)) %
963 (unsigned long) operandLitValue (right) :
964 (long) operandLitValue (right)));
968 retval = operandFromLit (((SPEC_USIGN(let) ?
969 (unsigned long) operandLitValue (left) :
970 (long) operandLitValue (left)) <<
972 (unsigned long) operandLitValue (right) :
973 (long) operandLitValue (right))));
976 retval = operandFromLit (((SPEC_USIGN(let) ?
977 (unsigned long) operandLitValue (left) :
978 (long) operandLitValue (left)) >>
980 (unsigned long) operandLitValue (right) :
981 (long) operandLitValue (right))));
984 retval = operandFromLit (operandLitValue (left) ==
985 operandLitValue (right));
988 retval = operandFromLit (operandLitValue (left) <
989 operandLitValue (right));
992 retval = operandFromLit (operandLitValue (left) <=
993 operandLitValue (right));
996 retval = operandFromLit (operandLitValue (left) !=
997 operandLitValue (right));
1000 retval = operandFromLit (operandLitValue (left) >
1001 operandLitValue (right));
1004 retval = operandFromLit (operandLitValue (left) >=
1005 operandLitValue (right));
1008 retval = operandFromLit ((unsigned long) operandLitValue (left) &
1009 (unsigned long) operandLitValue (right));
1012 retval = operandFromLit ((unsigned long) operandLitValue (left) |
1013 (unsigned long) operandLitValue (right));
1016 retval = operandFromLit ((unsigned long) operandLitValue (left) ^
1017 (unsigned long) operandLitValue (right));
1020 retval = operandFromLit (operandLitValue (left) &&
1021 operandLitValue (right));
1024 retval = operandFromLit (operandLitValue (left) ||
1025 operandLitValue (right));
1029 long i = (long) operandLitValue (left);
1031 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1037 long i = (long) operandLitValue (left);
1039 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1045 retval = operandFromLit (-1 * operandLitValue (left));
1049 retval = operandFromLit (~((long) operandLitValue (left)));
1053 retval = operandFromLit (!operandLitValue (left));
1057 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1058 " operandOperation invalid operator ");
1066 /*-----------------------------------------------------------------*/
1067 /* isOperandEqual - compares two operand & return 1 if they r = */
1068 /*-----------------------------------------------------------------*/
1070 isOperandEqual (operand * left, operand * right)
1072 /* if the pointers are equal then they are equal */
1076 /* if either of them null then false */
1077 if (!left || !right)
1080 if (left->type != right->type)
1083 if (IS_SYMOP (left) && IS_SYMOP (right))
1084 return left->key == right->key;
1086 /* if types are the same */
1090 return isSymbolEqual (left->operand.symOperand,
1091 right->operand.symOperand);
1093 return (floatFromVal (left->operand.valOperand) ==
1094 floatFromVal (right->operand.valOperand));
1096 if (compareType (left->operand.typeOperand,
1097 right->operand.typeOperand) == 1)
1104 /*-----------------------------------------------------------------*/
1105 /* isiCodeEqual - comapres two iCodes are returns true if yes */
1106 /*-----------------------------------------------------------------*/
1108 isiCodeEqual (iCode * left, iCode * right)
1110 /* if the same pointer */
1114 /* if either of them null */
1115 if (!left || !right)
1118 /* if operand are the same */
1119 if (left->op == right->op)
1122 /* compare all the elements depending on type */
1123 if (left->op != IFX)
1125 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1127 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1133 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1135 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1137 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1145 /*-----------------------------------------------------------------*/
1146 /* newiTempFromOp - create a temp Operand with same attributes */
1147 /*-----------------------------------------------------------------*/
1149 newiTempFromOp (operand * op)
1159 nop = newiTempOperand (operandType (op), TRUE);
1160 nop->isaddr = op->isaddr;
1161 nop->isvolatile = op->isvolatile;
1162 nop->isGlobal = op->isGlobal;
1163 nop->isLiteral = op->isLiteral;
1164 nop->usesDefs = op->usesDefs;
1165 nop->isParm = op->isParm;
1169 /*-----------------------------------------------------------------*/
1170 /* operand from operand - creates an operand holder for the type */
1171 /*-----------------------------------------------------------------*/
1173 operandFromOperand (operand * op)
1179 nop = newOperand ();
1180 nop->type = op->type;
1181 nop->isaddr = op->isaddr;
1183 nop->isvolatile = op->isvolatile;
1184 nop->isGlobal = op->isGlobal;
1185 nop->isLiteral = op->isLiteral;
1186 nop->usesDefs = op->usesDefs;
1187 nop->isParm = op->isParm;
1192 nop->operand.symOperand = op->operand.symOperand;
1195 nop->operand.valOperand = op->operand.valOperand;
1198 nop->operand.typeOperand = op->operand.typeOperand;
1205 /*-----------------------------------------------------------------*/
1206 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1207 /*-----------------------------------------------------------------*/
1209 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1211 operand *nop = operandFromOperand (op);
1213 if (nop->type == SYMBOL)
1215 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1216 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1222 /*-----------------------------------------------------------------*/
1223 /* operandFromSymbol - creates an operand from a symbol */
1224 /*-----------------------------------------------------------------*/
1226 operandFromSymbol (symbol * sym)
1231 /* if the symbol's type is a literal */
1232 /* then it is an enumerator type */
1233 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1234 return operandFromValue (valFromType (sym->etype));
1237 sym->key = ++operandKey;
1239 /* if this an implicit variable, means struct/union */
1240 /* member so just return it */
1241 if (sym->implicit || IS_FUNC (sym->type))
1245 op->operand.symOperand = sym;
1247 op->isvolatile = isOperandVolatile (op, TRUE);
1248 op->isGlobal = isOperandGlobal (op);
1252 /* under the following conditions create a
1253 register equivalent for a local symbol */
1254 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1255 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1256 /* (!TARGET_IS_DS390)) && */
1257 (!(options.model == MODEL_FLAT24)) ) &&
1258 options.stackAuto == 0)
1261 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1262 !IS_FUNC (sym->type) && /* not a function */
1263 !sym->_isparm && /* not a parameter */
1264 sym->level && /* is a local variable */
1265 !sym->addrtaken && /* whose address has not been taken */
1266 !sym->reqv && /* does not already have a register euivalence */
1267 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1268 !IS_STATIC (sym->etype) && /* and not declared static */
1269 !sym->islbl && /* not a label */
1270 ok && /* farspace check */
1271 !IS_BITVAR (sym->etype) /* not a bit variable */
1275 /* we will use it after all optimizations
1276 and before liveRange calculation */
1277 sym->reqv = newiTempOperand (sym->type, 0);
1278 sym->reqv->key = sym->key;
1279 OP_SYMBOL (sym->reqv)->key = sym->key;
1280 OP_SYMBOL (sym->reqv)->isreqv = 1;
1281 OP_SYMBOL (sym->reqv)->islocal = 1;
1282 SPIL_LOC (sym->reqv) = sym;
1285 if (!IS_AGGREGATE (sym->type))
1289 op->operand.symOperand = sym;
1292 op->isvolatile = isOperandVolatile (op, TRUE);
1293 op->isGlobal = isOperandGlobal (op);
1294 op->isPtr = IS_PTR (operandType (op));
1295 op->isParm = sym->_isparm;
1300 /* itemp = &[_symbol] */
1302 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1303 IC_LEFT (ic)->type = SYMBOL;
1304 IC_LEFT (ic)->operand.symOperand = sym;
1305 IC_LEFT (ic)->key = sym->key;
1306 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1307 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1308 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1311 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1312 if (IS_ARRAY (sym->type))
1314 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1315 IC_RESULT (ic)->isaddr = 0;
1318 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1320 IC_RESULT (ic)->operand.symOperand->args = sym->args;
1324 return IC_RESULT (ic);
1327 /*-----------------------------------------------------------------*/
1328 /* operandFromValue - creates an operand from value */
1329 /*-----------------------------------------------------------------*/
1331 operandFromValue (value * val)
1335 /* if this is a symbol then do the symbol thing */
1337 return operandFromSymbol (val->sym);
1339 /* this is not a symbol */
1342 op->operand.valOperand = val;
1343 op->isLiteral = isOperandLiteral (op);
1347 /*-----------------------------------------------------------------*/
1348 /* operandFromLink - operand from typeChain */
1349 /*-----------------------------------------------------------------*/
1351 operandFromLink (sym_link * type)
1355 /* operand from sym_link */
1361 op->operand.typeOperand = copyLinkChain (type);
1365 /*-----------------------------------------------------------------*/
1366 /* operandFromLit - makes an operand from a literal value */
1367 /*-----------------------------------------------------------------*/
1369 operandFromLit (double i)
1371 return operandFromValue (valueFromLit (i));
1374 /*-----------------------------------------------------------------*/
1375 /* operandFromAst - creates an operand from an ast */
1376 /*-----------------------------------------------------------------*/
1378 operandFromAst (ast * tree,int lvl)
1384 /* depending on type do */
1388 return ast2iCode (tree,lvl+1);
1392 return operandFromValue (tree->opval.val);
1396 return operandFromLink (tree->opval.lnk);
1400 /* Just to keep the comiler happy */
1401 return (operand *) 0;
1404 /*-----------------------------------------------------------------*/
1405 /* setOperandType - sets the operand's type to the given type */
1406 /*-----------------------------------------------------------------*/
1408 setOperandType (operand * op, sym_link * type)
1410 /* depending on the type of operand */
1415 op->operand.valOperand->etype =
1416 getSpec (op->operand.valOperand->type =
1417 copyLinkChain (type));
1421 if (op->operand.symOperand->isitmp)
1422 op->operand.symOperand->etype =
1423 getSpec (op->operand.symOperand->type =
1424 copyLinkChain (type));
1426 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1427 "attempt to modify type of source");
1431 op->operand.typeOperand = copyLinkChain (type);
1436 /*-----------------------------------------------------------------*/
1437 /* Get size in byte of ptr need to access an array */
1438 /*-----------------------------------------------------------------*/
1440 getArraySizePtr (operand * op)
1442 sym_link *ltype = operandType(op);
1446 int size = getSize(ltype);
1447 return(IS_GENPTR(ltype)?(size-1):size);
1452 sym_link *letype = getSpec(ltype);
1453 switch (PTR_TYPE (SPEC_OCLS (letype)))
1465 return (GPTRSIZE-1);
1474 /*-----------------------------------------------------------------*/
1475 /* perform "usual unary conversions" */
1476 /*-----------------------------------------------------------------*/
1478 usualUnaryConversions (operand * op)
1480 if (IS_INTEGRAL (operandType (op)))
1482 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1485 return geniCodeCast (INTTYPE, op, TRUE);
1491 /*-----------------------------------------------------------------*/
1492 /* perform "usual binary conversions" */
1493 /*-----------------------------------------------------------------*/
1495 usualBinaryConversions (operand ** op1, operand ** op2)
1498 sym_link *rtype = operandType (*op2);
1499 sym_link *ltype = operandType (*op1);
1501 ctype = computeType (ltype, rtype);
1502 *op1 = geniCodeCast (ctype, *op1, TRUE);
1503 *op2 = geniCodeCast (ctype, *op2, TRUE);
1508 /*-----------------------------------------------------------------*/
1509 /* geniCodeValueAtAddress - generate intermeditate code for value */
1511 /*-----------------------------------------------------------------*/
1513 geniCodeRValue (operand * op, bool force)
1516 sym_link *type = operandType (op);
1517 sym_link *etype = getSpec (type);
1519 /* if this is an array & already */
1520 /* an address then return this */
1521 if (IS_AGGREGATE (type) ||
1522 (IS_PTR (type) && !force && !op->isaddr))
1523 return operandFromOperand (op);
1525 /* if this is not an address then must be */
1526 /* rvalue already so return this one */
1530 /* if this is not a temp symbol then */
1531 if (!IS_ITEMP (op) &&
1533 !IN_FARSPACE (SPEC_OCLS (etype)))
1535 op = operandFromOperand (op);
1540 if (IS_SPEC (type) &&
1541 IS_TRUE_SYMOP (op) &&
1542 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1543 /* TARGET_IS_DS390)) */
1544 (options.model == MODEL_FLAT24) ))
1546 op = operandFromOperand (op);
1551 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1552 if (IS_PTR (type) && op->isaddr && force)
1555 type = copyLinkChain (type);
1557 IC_RESULT (ic) = newiTempOperand (type, 1);
1558 IC_RESULT (ic)->isaddr = 0;
1560 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1562 /* if the right is a symbol */
1563 if (op->type == SYMBOL)
1564 IC_RESULT (ic)->operand.symOperand->args =
1565 op->operand.symOperand->args;
1568 return IC_RESULT (ic);
1571 /*-----------------------------------------------------------------*/
1572 /* geniCodeCast - changes the value from one type to another */
1573 /*-----------------------------------------------------------------*/
1575 geniCodeCast (sym_link * type, operand * op, bool implicit)
1579 sym_link *opetype = getSpec (optype = operandType (op));
1582 /* one of them has size zero then error */
1583 if (IS_VOID (optype))
1585 werror (E_CAST_ZERO);
1589 /* if the operand is already the desired type then do nothing */
1590 if (compareType (type, optype) == 1)
1593 /* if this is a literal then just change the type & return */
1594 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1595 return operandFromValue (valCastLiteral (type,
1596 operandLitValue (op)));
1598 /* if casting to some pointer type &&
1599 the destination is not a generic pointer
1600 then give a warning : (only for implicit casts) */
1601 if (IS_PTR (optype) && implicit &&
1602 (DCL_TYPE (optype) != DCL_TYPE (type)) &&
1605 werror (W_INCOMPAT_CAST);
1606 fprintf (stderr, "from type '");
1607 printTypeChain (optype, stderr);
1608 fprintf (stderr, "' to type '");
1609 printTypeChain (type, stderr);
1610 fprintf (stderr, "'\n");
1613 /* if they are the same size create an assignment */
1614 if (getSize (type) == getSize (optype) &&
1615 !IS_BITFIELD (type) &&
1617 !IS_FLOAT (optype) &&
1618 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1619 (!IS_SPEC (type) && !IS_SPEC (optype))))
1622 ic = newiCode ('=', NULL, op);
1623 IC_RESULT (ic) = newiTempOperand (type, 0);
1624 SPIL_LOC (IC_RESULT (ic)) =
1625 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1626 IC_RESULT (ic)->isaddr = 0;
1630 ic = newiCode (CAST, operandFromLink (type),
1631 geniCodeRValue (op, FALSE));
1633 IC_RESULT (ic) = newiTempOperand (type, 0);
1636 /* preserve the storage class & output class */
1637 /* of the original variable */
1638 restype = getSpec (operandType (IC_RESULT (ic)));
1639 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1640 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1643 return IC_RESULT (ic);
1646 /*-----------------------------------------------------------------*/
1647 /* geniCodeLabel - will create a Label */
1648 /*-----------------------------------------------------------------*/
1650 geniCodeLabel (symbol * label)
1654 ic = newiCodeLabelGoto (LABEL, label);
1658 /*-----------------------------------------------------------------*/
1659 /* geniCodeGoto - will create a Goto */
1660 /*-----------------------------------------------------------------*/
1662 geniCodeGoto (symbol * label)
1666 ic = newiCodeLabelGoto (GOTO, label);
1670 /*-----------------------------------------------------------------*/
1671 /* geniCodeMultiply - gen intermediate code for multiplication */
1672 /*-----------------------------------------------------------------*/
1674 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1681 /* if they are both literal then we know the result */
1682 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1683 return operandFromValue (valMult (left->operand.valOperand,
1684 right->operand.valOperand));
1686 if (IS_LITERAL(retype)) {
1687 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1690 resType = usualBinaryConversions (&left, &right);
1692 rtype = operandType (right);
1693 retype = getSpec (rtype);
1694 ltype = operandType (left);
1695 letype = getSpec (ltype);
1699 SPEC_NOUN(getSpec(resType))=V_INT;
1702 /* if the right is a literal & power of 2 */
1703 /* then make it a left shift */
1704 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1705 efficient in most cases than 2 bytes result = 2 bytes << literal
1706 if port has 1 byte muldiv */
1707 if (p2 && !IS_FLOAT (letype) &&
1708 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1709 (port->support.muldiv == 1)))
1711 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1713 /* LEFT_OP need same size for left and result, */
1714 left = geniCodeCast (resType, left, TRUE);
1715 ltype = operandType (left);
1717 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1721 ic = newiCode ('*', left, right); /* normal multiplication */
1722 /* if the size left or right > 1 then support routine */
1723 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1727 IC_RESULT (ic) = newiTempOperand (resType, 1);
1730 return IC_RESULT (ic);
1733 /*-----------------------------------------------------------------*/
1734 /* geniCodeDivision - gen intermediate code for division */
1735 /*-----------------------------------------------------------------*/
1737 geniCodeDivision (operand * left, operand * right)
1742 sym_link *rtype = operandType (right);
1743 sym_link *retype = getSpec (rtype);
1744 sym_link *ltype = operandType (left);
1745 sym_link *letype = getSpec (ltype);
1747 resType = usualBinaryConversions (&left, &right);
1749 /* if the right is a literal & power of 2 */
1750 /* then make it a right shift */
1751 if (IS_LITERAL (retype) &&
1752 !IS_FLOAT (letype) &&
1753 (p2 = powof2 ((unsigned long)
1754 floatFromVal (right->operand.valOperand)))) {
1755 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1759 ic = newiCode ('/', left, right); /* normal division */
1760 /* if the size left or right > 1 then support routine */
1761 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1764 IC_RESULT (ic) = newiTempOperand (resType, 0);
1767 return IC_RESULT (ic);
1769 /*-----------------------------------------------------------------*/
1770 /* geniCodeModulus - gen intermediate code for modulus */
1771 /*-----------------------------------------------------------------*/
1773 geniCodeModulus (operand * left, operand * right)
1779 /* if they are both literal then we know the result */
1780 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1781 return operandFromValue (valMod (left->operand.valOperand,
1782 right->operand.valOperand));
1784 resType = usualBinaryConversions (&left, &right);
1786 /* now they are the same size */
1787 ic = newiCode ('%', left, right);
1789 /* if the size left or right > 1 then support routine */
1790 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1792 IC_RESULT (ic) = newiTempOperand (resType, 0);
1795 return IC_RESULT (ic);
1798 /*-----------------------------------------------------------------*/
1799 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1800 /*-----------------------------------------------------------------*/
1802 geniCodePtrPtrSubtract (operand * left, operand * right)
1808 /* if they are both literals then */
1809 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1811 result = operandFromValue (valMinus (left->operand.valOperand,
1812 right->operand.valOperand));
1816 ic = newiCode ('-', left, right);
1818 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1822 return geniCodeDivision (result,
1823 operandFromLit (getSize (ltype->next)));
1826 /*-----------------------------------------------------------------*/
1827 /* geniCodeSubtract - generates code for subtraction */
1828 /*-----------------------------------------------------------------*/
1830 geniCodeSubtract (operand * left, operand * right)
1837 /* if they both pointers then */
1838 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1839 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1840 return geniCodePtrPtrSubtract (left, right);
1842 /* if they are both literal then we know the result */
1843 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1844 && left->isLiteral && right->isLiteral)
1845 return operandFromValue (valMinus (left->operand.valOperand,
1846 right->operand.valOperand));
1848 /* if left is an array or pointer */
1849 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1851 isarray = left->isaddr;
1852 right = geniCodeMultiply (right,
1853 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1854 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1857 { /* make them the same size */
1858 resType = usualBinaryConversions (&left, &right);
1861 ic = newiCode ('-', left, right);
1863 IC_RESULT (ic) = newiTempOperand (resType, 1);
1864 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1866 /* if left or right is a float */
1867 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1871 return IC_RESULT (ic);
1874 /*-----------------------------------------------------------------*/
1875 /* geniCodeAdd - generates iCode for addition */
1876 /*-----------------------------------------------------------------*/
1878 geniCodeAdd (operand * left, operand * right,int lvl)
1886 /* if left is an array then array access */
1887 if (IS_ARRAY (ltype))
1888 return geniCodeArray (left, right,lvl);
1890 /* if the right side is LITERAL zero */
1891 /* return the left side */
1892 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1895 /* if left is literal zero return right */
1896 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1899 /* if left is an array or pointer then size */
1902 isarray = left->isaddr;
1903 // there is no need to multiply with 1
1904 if (getSize(ltype->next)!=1) {
1905 size = operandFromLit (getSize (ltype->next));
1906 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1908 resType = copyLinkChain (ltype);
1911 { /* make them the same size */
1912 resType = usualBinaryConversions (&left, &right);
1915 /* if they are both literals then we know */
1916 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1917 && left->isLiteral && right->isLiteral)
1918 return operandFromValue (valPlus (valFromType (letype),
1919 valFromType (retype)));
1921 ic = newiCode ('+', left, right);
1923 IC_RESULT (ic) = newiTempOperand (resType, 1);
1924 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1926 /* if left or right is a float then support
1928 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1933 return IC_RESULT (ic);
1937 /*-----------------------------------------------------------------*/
1938 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1939 /*-----------------------------------------------------------------*/
1941 aggrToPtr (sym_link * type, bool force)
1947 if (IS_PTR (type) && !force)
1950 etype = getSpec (type);
1954 /* if the output class is generic */
1955 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
1956 DCL_PTR_CONST (ptype) = port->mem.code_ro;
1958 /* if the variable was declared a constant */
1959 /* then the pointer points to a constant */
1960 if (IS_CONSTANT (etype))
1961 DCL_PTR_CONST (ptype) = 1;
1963 /* the variable was volatile then pointer to volatile */
1964 if (IS_VOLATILE (etype))
1965 DCL_PTR_VOLATILE (ptype) = 1;
1969 /*-----------------------------------------------------------------*/
1970 /* geniCodeArray2Ptr - array to pointer */
1971 /*-----------------------------------------------------------------*/
1973 geniCodeArray2Ptr (operand * op)
1975 sym_link *optype = operandType (op);
1976 sym_link *opetype = getSpec (optype);
1978 /* set the pointer depending on the storage class */
1979 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
1980 DCL_PTR_CONST (optype) = port->mem.code_ro;
1983 /* if the variable was declared a constant */
1984 /* then the pointer points to a constant */
1985 if (IS_CONSTANT (opetype))
1986 DCL_PTR_CONST (optype) = 1;
1988 /* the variable was volatile then pointer to volatile */
1989 if (IS_VOLATILE (opetype))
1990 DCL_PTR_VOLATILE (optype) = 1;
1996 /*-----------------------------------------------------------------*/
1997 /* geniCodeArray - array access */
1998 /*-----------------------------------------------------------------*/
2000 geniCodeArray (operand * left, operand * right,int lvl)
2003 sym_link *ltype = operandType (left);
2007 if (IS_PTR (ltype->next) && left->isaddr)
2009 left = geniCodeRValue (left, FALSE);
2011 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2014 right = geniCodeMultiply (right,
2015 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2017 /* we can check for limits here */
2018 if (isOperandLiteral (right) &&
2021 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2023 werror (E_ARRAY_BOUND);
2024 right = operandFromLit (0);
2027 ic = newiCode ('+', left, right);
2029 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2030 !IS_AGGREGATE (ltype->next) &&
2031 !IS_PTR (ltype->next))
2032 ? ltype : ltype->next), 0);
2034 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2036 return IC_RESULT (ic);
2039 /*-----------------------------------------------------------------*/
2040 /* geniCodeStruct - generates intermediate code for structres */
2041 /*-----------------------------------------------------------------*/
2043 geniCodeStruct (operand * left, operand * right, bool islval)
2046 sym_link *type = operandType (left);
2047 sym_link *etype = getSpec (type);
2049 symbol *element = getStructElement (SPEC_STRUCT (etype),
2050 right->operand.symOperand);
2052 /* add the offset */
2053 ic = newiCode ('+', left, operandFromLit (element->offset));
2055 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2057 /* preserve the storage & output class of the struct */
2058 /* as well as the volatile attribute */
2059 retype = getSpec (operandType (IC_RESULT (ic)));
2060 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2061 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2062 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2064 if (IS_PTR (element->type))
2065 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2067 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2071 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2074 /*-----------------------------------------------------------------*/
2075 /* geniCodePostInc - generate int code for Post increment */
2076 /*-----------------------------------------------------------------*/
2078 geniCodePostInc (operand * op)
2082 sym_link *optype = operandType (op);
2084 operand *rv = (IS_ITEMP (op) ?
2085 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2087 sym_link *rvtype = operandType (rv);
2090 /* if this is not an address we have trouble */
2093 werror (E_LVALUE_REQUIRED, "++");
2097 rOp = newiTempOperand (rvtype, 0);
2098 OP_SYMBOL(rOp)->noSpilLoc = 1;
2101 OP_SYMBOL(rv)->noSpilLoc = 1;
2103 geniCodeAssign (rOp, rv, 0);
2105 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2106 if (IS_FLOAT (rvtype))
2107 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2109 ic = newiCode ('+', rv, operandFromLit (size));
2111 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2114 geniCodeAssign (op, result, 0);
2120 /*-----------------------------------------------------------------*/
2121 /* geniCodePreInc - generate code for preIncrement */
2122 /*-----------------------------------------------------------------*/
2124 geniCodePreInc (operand * op)
2127 sym_link *optype = operandType (op);
2128 operand *rop = (IS_ITEMP (op) ?
2129 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2131 sym_link *roptype = operandType (rop);
2137 werror (E_LVALUE_REQUIRED, "++");
2142 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2143 if (IS_FLOAT (roptype))
2144 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2146 ic = newiCode ('+', rop, operandFromLit (size));
2147 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2151 return geniCodeAssign (op, result, 0);
2154 /*-----------------------------------------------------------------*/
2155 /* geniCodePostDec - generates code for Post decrement */
2156 /*-----------------------------------------------------------------*/
2158 geniCodePostDec (operand * op)
2162 sym_link *optype = operandType (op);
2164 operand *rv = (IS_ITEMP (op) ?
2165 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2167 sym_link *rvtype = operandType (rv);
2170 /* if this is not an address we have trouble */
2173 werror (E_LVALUE_REQUIRED, "--");
2177 rOp = newiTempOperand (rvtype, 0);
2178 OP_SYMBOL(rOp)->noSpilLoc = 1;
2181 OP_SYMBOL(rv)->noSpilLoc = 1;
2183 geniCodeAssign (rOp, rv, 0);
2185 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2186 if (IS_FLOAT (rvtype))
2187 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2189 ic = newiCode ('-', rv, operandFromLit (size));
2191 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2194 geniCodeAssign (op, result, 0);
2200 /*-----------------------------------------------------------------*/
2201 /* geniCodePreDec - generate code for pre decrement */
2202 /*-----------------------------------------------------------------*/
2204 geniCodePreDec (operand * op)
2207 sym_link *optype = operandType (op);
2208 operand *rop = (IS_ITEMP (op) ?
2209 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2211 sym_link *roptype = operandType (rop);
2217 werror (E_LVALUE_REQUIRED, "--");
2222 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2223 if (IS_FLOAT (roptype))
2224 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2226 ic = newiCode ('-', rop, operandFromLit (size));
2227 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2231 return geniCodeAssign (op, result, 0);
2235 /*-----------------------------------------------------------------*/
2236 /* geniCodeBitwise - gen int code for bitWise operators */
2237 /*-----------------------------------------------------------------*/
2239 geniCodeBitwise (operand * left, operand * right,
2240 int oper, sym_link * resType)
2244 left = geniCodeCast (resType, left, TRUE);
2245 right = geniCodeCast (resType, right, TRUE);
2247 ic = newiCode (oper, left, right);
2248 IC_RESULT (ic) = newiTempOperand (resType, 0);
2251 return IC_RESULT (ic);
2254 /*-----------------------------------------------------------------*/
2255 /* geniCodeAddressOf - gens icode for '&' address of operator */
2256 /*-----------------------------------------------------------------*/
2258 geniCodeAddressOf (operand * op)
2262 sym_link *optype = operandType (op);
2263 sym_link *opetype = getSpec (optype);
2265 /* lvalue check already done in decorateType */
2266 /* this must be a lvalue */
2267 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2268 /* werror (E_LVALUE_REQUIRED,"&"); */
2273 p->class = DECLARATOR;
2275 /* set the pointer depending on the storage class */
2276 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2277 DCL_PTR_CONST (p) = port->mem.code_ro;
2279 /* make sure we preserve the const & volatile */
2280 if (IS_CONSTANT (opetype))
2281 DCL_PTR_CONST (p) = 1;
2283 if (IS_VOLATILE (opetype))
2284 DCL_PTR_VOLATILE (p) = 1;
2286 p->next = copyLinkChain (optype);
2288 /* if already a temp */
2291 setOperandType (op, p);
2296 /* other wise make this of the type coming in */
2297 ic = newiCode (ADDRESS_OF, op, NULL);
2298 IC_RESULT (ic) = newiTempOperand (p, 1);
2299 IC_RESULT (ic)->isaddr = 0;
2301 return IC_RESULT (ic);
2303 /*-----------------------------------------------------------------*/
2304 /* setOClass - sets the output class depending on the pointer type */
2305 /*-----------------------------------------------------------------*/
2307 setOClass (sym_link * ptr, sym_link * spec)
2309 switch (DCL_TYPE (ptr))
2312 SPEC_OCLS (spec) = data;
2316 SPEC_OCLS (spec) = generic;
2320 SPEC_OCLS (spec) = xdata;
2324 SPEC_OCLS (spec) = code;
2328 SPEC_OCLS (spec) = idata;
2332 SPEC_OCLS (spec) = xstack;
2336 SPEC_OCLS (spec) = eeprom;
2345 /*-----------------------------------------------------------------*/
2346 /* geniCodeDerefPtr - dereference pointer with '*' */
2347 /*-----------------------------------------------------------------*/
2349 geniCodeDerefPtr (operand * op,int lvl)
2351 sym_link *rtype, *retype;
2352 sym_link *optype = operandType (op);
2354 /* if this is a pointer then generate the rvalue */
2355 if (IS_PTR (optype))
2357 if (IS_TRUE_SYMOP (op))
2360 op = geniCodeRValue (op, TRUE);
2363 op = geniCodeRValue (op, TRUE);
2366 /* now get rid of the pointer part */
2367 if (isLvaluereq(lvl) && IS_ITEMP (op))
2369 retype = getSpec (rtype = copyLinkChain (optype));
2373 retype = getSpec (rtype = copyLinkChain (optype->next));
2376 /* if this is a pointer then outputclass needs 2b updated */
2377 if (IS_PTR (optype))
2378 setOClass (optype, retype);
2380 op->isGptr = IS_GENPTR (optype);
2382 /* if the pointer was declared as a constant */
2383 /* then we cannot allow assignment to the derefed */
2384 if (IS_PTR_CONST (optype))
2385 SPEC_CONST (retype) = 1;
2387 op->isaddr = (IS_PTR (rtype) ||
2388 IS_STRUCT (rtype) ||
2393 if (!isLvaluereq(lvl))
2394 op = geniCodeRValue (op, TRUE);
2396 setOperandType (op, rtype);
2401 /*-----------------------------------------------------------------*/
2402 /* geniCodeUnaryMinus - does a unary minus of the operand */
2403 /*-----------------------------------------------------------------*/
2405 geniCodeUnaryMinus (operand * op)
2408 sym_link *optype = operandType (op);
2410 if (IS_LITERAL (optype))
2411 return operandFromLit (-floatFromVal (op->operand.valOperand));
2413 ic = newiCode (UNARYMINUS, op, NULL);
2414 IC_RESULT (ic) = newiTempOperand (optype, 0);
2416 return IC_RESULT (ic);
2419 /*-----------------------------------------------------------------*/
2420 /* geniCodeLeftShift - gen i code for left shift */
2421 /*-----------------------------------------------------------------*/
2423 geniCodeLeftShift (operand * left, operand * right)
2427 ic = newiCode (LEFT_OP, left, right);
2428 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2430 return IC_RESULT (ic);
2433 /*-----------------------------------------------------------------*/
2434 /* geniCodeRightShift - gen i code for right shift */
2435 /*-----------------------------------------------------------------*/
2437 geniCodeRightShift (operand * left, operand * right)
2441 ic = newiCode (RIGHT_OP, left, right);
2442 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2444 return IC_RESULT (ic);
2447 /*-----------------------------------------------------------------*/
2448 /* geniCodeLogic- logic code */
2449 /*-----------------------------------------------------------------*/
2451 geniCodeLogic (operand * left, operand * right, int op)
2455 sym_link *rtype = operandType (right);
2456 sym_link *ltype = operandType (left);
2458 /* left is integral type and right is literal then
2459 check if the literal value is within bounds */
2460 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2462 checkConstantRange(ltype,
2463 operandLitValue(right), "compare operation", 1);
2466 ctype = usualBinaryConversions (&left, &right);
2468 ic = newiCode (op, left, right);
2469 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2471 /* if comparing float
2472 and not a '==' || '!=' || '&&' || '||' (these
2474 if (IS_FLOAT(ctype) &&
2482 return IC_RESULT (ic);
2485 /*-----------------------------------------------------------------*/
2486 /* geniCodeUnary - for a a generic unary operation */
2487 /*-----------------------------------------------------------------*/
2489 geniCodeUnary (operand * op, int oper)
2491 iCode *ic = newiCode (oper, op, NULL);
2493 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2495 return IC_RESULT (ic);
2498 /*-----------------------------------------------------------------*/
2499 /* geniCodeConditional - geniCode for '?' ':' operation */
2500 /*-----------------------------------------------------------------*/
2502 geniCodeConditional (ast * tree,int lvl)
2505 symbol *falseLabel = newiTempLabel (NULL);
2506 symbol *exitLabel = newiTempLabel (NULL);
2507 operand *cond = ast2iCode (tree->left,lvl+1);
2508 operand *true, *false, *result;
2510 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2514 true = ast2iCode (tree->right->left,lvl+1);
2516 /* move the value to a new Operand */
2517 result = newiTempOperand (operandType (true), 0);
2518 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2520 /* generate an unconditional goto */
2521 geniCodeGoto (exitLabel);
2523 /* now for the right side */
2524 geniCodeLabel (falseLabel);
2526 false = ast2iCode (tree->right->right,lvl+1);
2527 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2529 /* create the exit label */
2530 geniCodeLabel (exitLabel);
2535 /*-----------------------------------------------------------------*/
2536 /* geniCodeAssign - generate code for assignment */
2537 /*-----------------------------------------------------------------*/
2539 geniCodeAssign (operand * left, operand * right, int nosupdate)
2542 sym_link *ltype = operandType (left);
2543 sym_link *rtype = operandType (right);
2545 if (!left->isaddr && !IS_ITEMP (left))
2547 werror (E_LVALUE_REQUIRED, "assignment");
2551 /* left is integral type and right is literal then
2552 check if the literal value is within bounds */
2553 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2555 checkConstantRange(ltype,
2556 operandLitValue(right), "= operation", 0);
2559 /* if the left & right type don't exactly match */
2560 /* if pointer set then make sure the check is
2561 done with the type & not the pointer */
2562 /* then cast rights type to left */
2564 /* first check the type for pointer assignement */
2565 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2566 compareType (ltype, rtype) < 0)
2568 if (compareType (ltype->next, rtype) < 0)
2569 right = geniCodeCast (ltype->next, right, TRUE);
2571 else if (compareType (ltype, rtype) < 0)
2572 right = geniCodeCast (ltype, right, TRUE);
2574 /* if left is a true symbol & ! volatile
2575 create an assignment to temporary for
2576 the right & then assign this temporary
2577 to the symbol this is SSA . isn't it simple
2578 and folks have published mountains of paper on it */
2579 if (IS_TRUE_SYMOP (left) &&
2580 !isOperandVolatile (left, FALSE) &&
2581 isOperandGlobal (left))
2585 if (IS_TRUE_SYMOP (right))
2586 sym = OP_SYMBOL (right);
2587 ic = newiCode ('=', NULL, right);
2588 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2589 SPIL_LOC (right) = sym;
2593 ic = newiCode ('=', NULL, right);
2594 IC_RESULT (ic) = left;
2597 /* if left isgptr flag is set then support
2598 routine will be required */
2602 ic->nosupdate = nosupdate;
2606 /*-----------------------------------------------------------------*/
2607 /* geniCodeSEParms - generate code for side effecting fcalls */
2608 /*-----------------------------------------------------------------*/
2610 geniCodeSEParms (ast * parms,int lvl)
2615 if (parms->type == EX_OP && parms->opval.op == PARAM)
2617 geniCodeSEParms (parms->left,lvl);
2618 geniCodeSEParms (parms->right,lvl);
2622 /* hack don't like this but too lazy to think of
2624 if (IS_ADDRESS_OF_OP (parms))
2625 parms->left->lvalue = 1;
2627 if (IS_CAST_OP (parms) &&
2628 IS_PTR (parms->ftype) &&
2629 IS_ADDRESS_OF_OP (parms->right))
2630 parms->right->left->lvalue = 1;
2632 parms->opval.oprnd =
2633 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2635 parms->type = EX_OPERAND;
2638 /*-----------------------------------------------------------------*/
2639 /* geniCodeParms - generates parameters */
2640 /*-----------------------------------------------------------------*/
2642 geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl)
2650 /* if this is a param node then do the left & right */
2651 if (parms->type == EX_OP && parms->opval.op == PARAM)
2653 geniCodeParms (parms->left, stack, fetype, func,lvl);
2654 geniCodeParms (parms->right, stack, fetype, func,lvl);
2658 /* get the parameter value */
2659 if (parms->type == EX_OPERAND)
2660 pval = parms->opval.oprnd;
2663 /* maybe this else should go away ?? */
2664 /* hack don't like this but too lazy to think of
2666 if (IS_ADDRESS_OF_OP (parms))
2667 parms->left->lvalue = 1;
2669 if (IS_CAST_OP (parms) &&
2670 IS_PTR (parms->ftype) &&
2671 IS_ADDRESS_OF_OP (parms->right))
2672 parms->right->left->lvalue = 1;
2674 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2677 /* if register parm then make it a send */
2678 if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
2679 IS_REGPARM (parms->etype)) && !func->hasVargs)
2681 ic = newiCode (SEND, pval, NULL);
2686 /* now decide whether to push or assign */
2687 if (!(options.stackAuto || IS_RENT (fetype)))
2691 operand *top = operandFromSymbol (parms->argSym);
2692 geniCodeAssign (top, pval, 1);
2696 sym_link *p = operandType (pval);
2698 ic = newiCode (IPUSH, pval, NULL);
2700 /* update the stack adjustment */
2701 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2708 /*-----------------------------------------------------------------*/
2709 /* geniCodeCall - generates temp code for calling */
2710 /*-----------------------------------------------------------------*/
2712 geniCodeCall (operand * left, ast * parms,int lvl)
2716 sym_link *type, *etype;
2719 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2720 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2721 werror (E_FUNCTION_EXPECTED);
2725 /* take care of parameters with side-effecting
2726 function calls in them, this is required to take care
2727 of overlaying function parameters */
2728 geniCodeSEParms (parms,lvl);
2730 /* first the parameters */
2731 geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2733 /* now call : if symbol then pcall */
2734 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2735 ic = newiCode (PCALL, left, NULL);
2737 ic = newiCode (CALL, left, NULL);
2739 IC_ARGS (ic) = left->operand.symOperand->args;
2740 type = copyLinkChain (operandType (left)->next);
2741 etype = getSpec (type);
2742 SPEC_EXTR (etype) = 0;
2743 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2747 /* stack adjustment after call */
2748 ic->parmBytes = stack;
2753 /*-----------------------------------------------------------------*/
2754 /* geniCodeReceive - generate intermediate code for "receive" */
2755 /*-----------------------------------------------------------------*/
2757 geniCodeReceive (value * args)
2759 /* for all arguments that are passed in registers */
2763 if (IS_REGPARM (args->etype))
2765 operand *opr = operandFromValue (args);
2767 symbol *sym = OP_SYMBOL (opr);
2770 /* we will use it after all optimizations
2771 and before liveRange calculation */
2772 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2775 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2776 options.stackAuto == 0 &&
2777 /* !TARGET_IS_DS390) */
2778 (!(options.model == MODEL_FLAT24)) )
2783 opl = newiTempOperand (args->type, 0);
2785 sym->reqv->key = sym->key;
2786 OP_SYMBOL (sym->reqv)->key = sym->key;
2787 OP_SYMBOL (sym->reqv)->isreqv = 1;
2788 OP_SYMBOL (sym->reqv)->islocal = 0;
2789 SPIL_LOC (sym->reqv) = sym;
2793 ic = newiCode (RECEIVE, NULL, NULL);
2794 currFunc->recvSize = getSize (sym->etype);
2795 IC_RESULT (ic) = opr;
2803 /*-----------------------------------------------------------------*/
2804 /* geniCodeFunctionBody - create the function body */
2805 /*-----------------------------------------------------------------*/
2807 geniCodeFunctionBody (ast * tree,int lvl)
2814 /* reset the auto generation */
2820 func = ast2iCode (tree->left,lvl+1);
2821 fetype = getSpec (operandType (func));
2823 savelineno = lineno;
2824 lineno = OP_SYMBOL (func)->lineDef;
2825 /* create an entry label */
2826 geniCodeLabel (entryLabel);
2827 lineno = savelineno;
2829 /* create a proc icode */
2830 ic = newiCode (FUNCTION, func, NULL);
2831 /* if the function has parmas then */
2832 /* save the parameters information */
2833 ic->argLabel.args = tree->values.args;
2834 ic->lineno = OP_SYMBOL (func)->lineDef;
2838 /* for all parameters that are passed
2839 on registers add a "receive" */
2840 geniCodeReceive (tree->values.args);
2842 /* generate code for the body */
2843 ast2iCode (tree->right,lvl+1);
2845 /* create a label for return */
2846 geniCodeLabel (returnLabel);
2848 /* now generate the end proc */
2849 ic = newiCode (ENDFUNCTION, func, NULL);
2854 /*-----------------------------------------------------------------*/
2855 /* geniCodeReturn - gen icode for 'return' statement */
2856 /*-----------------------------------------------------------------*/
2858 geniCodeReturn (operand * op)
2862 /* if the operand is present force an rvalue */
2864 op = geniCodeRValue (op, FALSE);
2866 ic = newiCode (RETURN, op, NULL);
2870 /*-----------------------------------------------------------------*/
2871 /* geniCodeIfx - generates code for extended if statement */
2872 /*-----------------------------------------------------------------*/
2874 geniCodeIfx (ast * tree,int lvl)
2877 operand *condition = ast2iCode (tree->left,lvl+1);
2880 /* if condition is null then exit */
2884 condition = geniCodeRValue (condition, FALSE);
2886 cetype = getSpec (operandType (condition));
2887 /* if the condition is a literal */
2888 if (IS_LITERAL (cetype))
2890 if (floatFromVal (condition->operand.valOperand))
2892 if (tree->trueLabel)
2893 geniCodeGoto (tree->trueLabel);
2899 if (tree->falseLabel)
2900 geniCodeGoto (tree->falseLabel);
2907 if (tree->trueLabel)
2909 ic = newiCodeCondition (condition,
2914 if (tree->falseLabel)
2915 geniCodeGoto (tree->falseLabel);
2919 ic = newiCodeCondition (condition,
2926 ast2iCode (tree->right,lvl+1);
2929 /*-----------------------------------------------------------------*/
2930 /* geniCodeJumpTable - tries to create a jump table for switch */
2931 /*-----------------------------------------------------------------*/
2933 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2935 int min = 0, max = 0, t, cnt = 0;
2942 if (!tree || !caseVals)
2945 /* the criteria for creating a jump table is */
2946 /* all integer numbers between the maximum & minimum must */
2947 /* be present , the maximum value should not exceed 255 */
2948 min = max = (int) floatFromVal (vch = caseVals);
2949 sprintf (buffer, "_case_%d_%d",
2950 tree->values.switchVals.swNum,
2952 addSet (&labels, newiTempLabel (buffer));
2954 /* if there is only one case value then no need */
2955 if (!(vch = vch->next))
2960 if (((t = (int) floatFromVal (vch)) - max) != 1)
2962 sprintf (buffer, "_case_%d_%d",
2963 tree->values.switchVals.swNum,
2965 addSet (&labels, newiTempLabel (buffer));
2971 /* if the number of case statements <= 2 then */
2972 /* it is not economical to create the jump table */
2973 /* since two compares are needed for boundary conditions */
2974 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
2977 if (tree->values.switchVals.swDefault)
2978 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
2980 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
2982 falseLabel = newiTempLabel (buffer);
2984 /* so we can create a jumptable */
2985 /* first we rule out the boundary conditions */
2986 /* if only optimization says so */
2987 if (!optimize.noJTabBoundary)
2989 sym_link *cetype = getSpec (operandType (cond));
2990 /* no need to check the lower bound if
2991 the condition is unsigned & minimum value is zero */
2992 if (!(min == 0 && SPEC_USIGN (cetype)))
2994 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
2995 ic = newiCodeCondition (boundary, falseLabel, NULL);
2999 /* now for upper bounds */
3000 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3001 ic = newiCodeCondition (boundary, falseLabel, NULL);
3005 /* if the min is not zero then we no make it zero */
3008 cond = geniCodeSubtract (cond, operandFromLit (min));
3009 setOperandType (cond, UCHARTYPE);
3012 /* now create the jumptable */
3013 ic = newiCode (JUMPTABLE, NULL, NULL);
3014 IC_JTCOND (ic) = cond;
3015 IC_JTLABELS (ic) = labels;
3020 /*-----------------------------------------------------------------*/
3021 /* geniCodeSwitch - changes a switch to a if statement */
3022 /*-----------------------------------------------------------------*/
3024 geniCodeSwitch (ast * tree,int lvl)
3027 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3028 value *caseVals = tree->values.switchVals.swVals;
3029 symbol *trueLabel, *falseLabel;
3031 /* if we can make this a jump table */
3032 if (geniCodeJumpTable (cond, caseVals, tree))
3033 goto jumpTable; /* no need for the comparison */
3035 /* for the cases defined do */
3039 operand *compare = geniCodeLogic (cond,
3040 operandFromValue (caseVals),
3043 sprintf (buffer, "_case_%d_%d",
3044 tree->values.switchVals.swNum,
3045 (int) floatFromVal (caseVals));
3046 trueLabel = newiTempLabel (buffer);
3048 ic = newiCodeCondition (compare, trueLabel, NULL);
3050 caseVals = caseVals->next;
3055 /* if default is present then goto break else break */
3056 if (tree->values.switchVals.swDefault)
3057 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3059 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3061 falseLabel = newiTempLabel (buffer);
3062 geniCodeGoto (falseLabel);
3065 ast2iCode (tree->right,lvl+1);
3068 /*-----------------------------------------------------------------*/
3069 /* geniCodeInline - intermediate code for inline assembler */
3070 /*-----------------------------------------------------------------*/
3072 geniCodeInline (ast * tree)
3076 ic = newiCode (INLINEASM, NULL, NULL);
3077 IC_INLINE (ic) = tree->values.inlineasm;
3081 /*-----------------------------------------------------------------*/
3082 /* geniCodeArrayInit - intermediate code for array initializer */
3083 /*-----------------------------------------------------------------*/
3085 geniCodeArrayInit (ast * tree, operand *array)
3089 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3090 ic = newiCode (ARRAYINIT, array, NULL);
3091 IC_ARRAYILIST (ic) = tree->values.constlist;
3093 operand *left=newOperand(), *right=newOperand();
3094 left->type=right->type=SYMBOL;
3095 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3096 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3097 ic = newiCode (ARRAYINIT, left, right);
3102 /*-----------------------------------------------------------------*/
3103 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3104 /* particular case. Ie : assigning or dereferencing array or ptr */
3105 /*-----------------------------------------------------------------*/
3106 set * lvaluereqSet = NULL;
3107 typedef struct lvalItem
3114 /*-----------------------------------------------------------------*/
3115 /* addLvaluereq - add a flag for lvalreq for current ast level */
3116 /*-----------------------------------------------------------------*/
3117 void addLvaluereq(int lvl)
3119 lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
3122 addSetHead(&lvaluereqSet,lpItem);
3125 /*-----------------------------------------------------------------*/
3126 /* delLvaluereq - del a flag for lvalreq for current ast level */
3127 /*-----------------------------------------------------------------*/
3131 lpItem = getSet(&lvaluereqSet);
3132 if(lpItem) free(lpItem);
3134 /*-----------------------------------------------------------------*/
3135 /* clearLvaluereq - clear lvalreq flag */
3136 /*-----------------------------------------------------------------*/
3137 void clearLvaluereq()
3140 lpItem = peekSet(lvaluereqSet);
3141 if(lpItem) lpItem->req = 0;
3143 /*-----------------------------------------------------------------*/
3144 /* getLvaluereq - get the last lvalreq level */
3145 /*-----------------------------------------------------------------*/
3146 int getLvaluereqLvl()
3149 lpItem = peekSet(lvaluereqSet);
3150 if(lpItem) return lpItem->lvl;
3153 /*-----------------------------------------------------------------*/
3154 /* isLvaluereq - is lvalreq valid for this level ? */
3155 /*-----------------------------------------------------------------*/
3156 int isLvaluereq(int lvl)
3159 lpItem = peekSet(lvaluereqSet);
3160 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3164 /*-----------------------------------------------------------------*/
3165 /* ast2iCode - creates an icodeList from an ast */
3166 /*-----------------------------------------------------------------*/
3168 ast2iCode (ast * tree,int lvl)
3170 operand *left = NULL;
3171 operand *right = NULL;
3174 /* set the global variables for filename & line number */
3176 filename = tree->filename;
3178 lineno = tree->lineno;
3180 block = tree->block;
3182 scopeLevel = tree->level;
3184 if (tree->type == EX_VALUE)
3185 return operandFromValue (tree->opval.val);
3187 if (tree->type == EX_LINK)
3188 return operandFromLink (tree->opval.lnk);
3190 /* if we find a nullop */
3191 if (tree->type == EX_OP &&
3192 (tree->opval.op == NULLOP ||
3193 tree->opval.op == BLOCK))
3195 ast2iCode (tree->left,lvl+1);
3196 ast2iCode (tree->right,lvl+1);
3200 /* special cases for not evaluating */
3201 if (tree->opval.op != ':' &&
3202 tree->opval.op != '?' &&
3203 tree->opval.op != CALL &&
3204 tree->opval.op != IFX &&
3205 tree->opval.op != LABEL &&
3206 tree->opval.op != GOTO &&
3207 tree->opval.op != SWITCH &&
3208 tree->opval.op != FUNCTION &&
3209 tree->opval.op != INLINEASM)
3212 if (IS_ASSIGN_OP (tree->opval.op) ||
3213 IS_DEREF_OP (tree) ||
3214 (tree->opval.op == '&' && !tree->right) ||
3215 tree->opval.op == PTR_OP)
3218 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3219 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3222 left = operandFromAst (tree->left,lvl);
3224 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3225 left = geniCodeRValue (left, TRUE);
3229 left = operandFromAst (tree->left,lvl);
3231 if (tree->opval.op == INC_OP ||
3232 tree->opval.op == DEC_OP)
3235 right = operandFromAst (tree->right,lvl);
3240 right = operandFromAst (tree->right,lvl);
3244 /* now depending on the type of operand */
3245 /* this will be a biggy */
3246 switch (tree->opval.op)
3249 case '[': /* array operation */
3251 sym_link *ltype = operandType (left);
3252 left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3253 right = geniCodeRValue (right, TRUE);
3256 return geniCodeArray (left, right,lvl);
3258 case '.': /* structure dereference */
3259 if (IS_PTR (operandType (left)))
3260 left = geniCodeRValue (left, TRUE);
3262 left = geniCodeRValue (left, FALSE);
3264 return geniCodeStruct (left, right, tree->lvalue);
3266 case PTR_OP: /* structure pointer dereference */
3269 pType = operandType (left);
3270 left = geniCodeRValue (left, TRUE);
3272 setOClass (pType, getSpec (operandType (left)));
3275 return geniCodeStruct (left, right, tree->lvalue);
3277 case INC_OP: /* increment operator */
3279 return geniCodePostInc (left);
3281 return geniCodePreInc (right);
3283 case DEC_OP: /* decrement operator */
3285 return geniCodePostDec (left);
3287 return geniCodePreDec (right);
3289 case '&': /* bitwise and or address of operator */
3291 { /* this is a bitwise operator */
3292 left = geniCodeRValue (left, FALSE);
3293 right = geniCodeRValue (right, FALSE);
3294 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3297 return geniCodeAddressOf (left);
3299 case '|': /* bitwise or & xor */
3301 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3302 geniCodeRValue (right, FALSE),
3307 return geniCodeDivision (geniCodeRValue (left, FALSE),
3308 geniCodeRValue (right, FALSE));
3311 return geniCodeModulus (geniCodeRValue (left, FALSE),
3312 geniCodeRValue (right, FALSE));
3315 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3316 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3318 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3322 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3323 geniCodeRValue (right, FALSE));
3325 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3329 return geniCodeAdd (geniCodeRValue (left, FALSE),
3330 geniCodeRValue (right, FALSE),lvl);
3332 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3335 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3336 geniCodeRValue (right, FALSE));
3339 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3340 geniCodeRValue (right, FALSE));
3342 return geniCodeCast (operandType (left),
3343 geniCodeRValue (right, FALSE), FALSE);
3349 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3353 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3354 setOperandType (op, UCHARTYPE);
3365 return geniCodeLogic (geniCodeRValue (left, FALSE),
3366 geniCodeRValue (right, FALSE),
3369 return geniCodeConditional (tree,lvl);
3372 return operandFromLit (getSize (tree->right->ftype));
3376 sym_link *rtype = operandType (right);
3377 sym_link *ltype = operandType (left);
3378 if (IS_PTR (rtype) && IS_ITEMP (right)
3379 && right->isaddr && compareType (rtype->next, ltype) == 1)
3380 right = geniCodeRValue (right, TRUE);
3382 right = geniCodeRValue (right, FALSE);
3384 geniCodeAssign (left, right, 0);
3389 geniCodeAssign (left,
3390 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3392 geniCodeRValue (right, FALSE),FALSE), 0);
3396 geniCodeAssign (left,
3397 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3399 geniCodeRValue (right, FALSE)), 0);
3402 geniCodeAssign (left,
3403 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3405 geniCodeRValue (right, FALSE)), 0);
3408 sym_link *rtype = operandType (right);
3409 sym_link *ltype = operandType (left);
3410 if (IS_PTR (rtype) && IS_ITEMP (right)
3411 && right->isaddr && compareType (rtype->next, ltype) == 1)
3412 right = geniCodeRValue (right, TRUE);
3414 right = geniCodeRValue (right, FALSE);
3417 return geniCodeAssign (left,
3418 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3424 sym_link *rtype = operandType (right);
3425 sym_link *ltype = operandType (left);
3426 if (IS_PTR (rtype) && IS_ITEMP (right)
3427 && right->isaddr && compareType (rtype->next, ltype) == 1)
3429 right = geniCodeRValue (right, TRUE);
3433 right = geniCodeRValue (right, FALSE);
3436 geniCodeAssign (left,
3437 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3443 geniCodeAssign (left,
3444 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3446 geniCodeRValue (right, FALSE)), 0);
3449 geniCodeAssign (left,
3450 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3452 geniCodeRValue (right, FALSE)), 0);
3455 geniCodeAssign (left,
3456 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3458 geniCodeRValue (right, FALSE),
3460 operandType (left)), 0);
3463 geniCodeAssign (left,
3464 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3466 geniCodeRValue (right, FALSE),
3468 operandType (left)), 0);
3471 geniCodeAssign (left,
3472 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3474 geniCodeRValue (right, FALSE),
3476 operandType (left)), 0);
3478 return geniCodeRValue (right, FALSE);
3481 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3484 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3485 return ast2iCode (tree->right,lvl+1);
3488 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3489 return ast2iCode (tree->right,lvl+1);
3492 geniCodeFunctionBody (tree,lvl);
3496 geniCodeReturn (right);
3500 geniCodeIfx (tree,lvl);
3504 geniCodeSwitch (tree,lvl);
3508 geniCodeInline (tree);
3512 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3519 /*-----------------------------------------------------------------*/
3520 /* reverseICChain - gets from the list and creates a linkedlist */
3521 /*-----------------------------------------------------------------*/
3528 while ((loop = getSet (&iCodeChain)))
3540 /*-----------------------------------------------------------------*/
3541 /* iCodeFromAst - given an ast will convert it to iCode */
3542 /*-----------------------------------------------------------------*/
3544 iCodeFromAst (ast * tree)
3546 returnLabel = newiTempLabel ("_return");
3547 entryLabel = newiTempLabel ("_entry");
3549 return reverseiCChain ();