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 /*-----------------------------------------------------------------*/
119 /* checkConstantRange: check a constant against the type */
120 /*-----------------------------------------------------------------*/
122 /* pedantic=0: allmost anything is allowed as long as the absolute
123 value is within the bit range of the type, and -1 is treated as
124 0xf..f for unsigned types (e.g. in assign)
125 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
126 pedantic>1: "char c=200" is not allowed (evaluates to -56)
129 void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
131 char message[132]="";
136 max = pow ((double)2.0, (double)bitsForType(ltype));
138 if (SPEC_LONG(val->type)) {
139 if (SPEC_USIGN(val->type)) {
140 v=SPEC_CVAL(val->type).v_ulong;
142 v=SPEC_CVAL(val->type).v_long;
145 if (SPEC_USIGN(val->type)) {
146 v=SPEC_CVAL(val->type).v_uint;
148 v=SPEC_CVAL(val->type).v_int;
154 // this could be a good idea
155 if (options.pedantic)
159 if (SPEC_NOUN(ltype)==FLOAT) {
164 if (!SPEC_USIGN(val->type) && v<0) {
166 if (SPEC_USIGN(ltype) && (pedantic>1)) {
172 // if very pedantic: "char c=200" is not allowed
173 if (pedantic>1 && !SPEC_USIGN(ltype)) {
174 max = max/2 + negative;
182 sprintf (message, "for %s %s in %s",
183 SPEC_USIGN(ltype) ? "unsigned" : "signed",
184 nounName(ltype), msg);
185 werror (W_CONST_RANGE, message);
192 /*-----------------------------------------------------------------*/
193 /* operandName - returns the name of the operand */
194 /*-----------------------------------------------------------------*/
196 printOperand (operand * op, FILE * file)
213 opetype = getSpec (operandType (op));
214 if (SPEC_NOUN (opetype) == V_FLOAT)
215 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
217 fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
218 printTypeChain (operandType (op), file);
225 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}" , */
226 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
228 OP_LIVEFROM (op), OP_LIVETO (op),
229 OP_SYMBOL (op)->stack,
230 op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
234 printTypeChain (operandType (op), file);
235 if (SPIL_LOC (op) && IS_ITEMP (op))
236 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
241 /* if assigned to registers */
242 if (OP_SYMBOL (op)->nRegs)
244 if (OP_SYMBOL (op)->isspilt)
246 if (!OP_SYMBOL (op)->remat)
247 if (OP_SYMBOL (op)->usl.spillLoc)
248 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
249 OP_SYMBOL (op)->usl.spillLoc->rname :
250 OP_SYMBOL (op)->usl.spillLoc->name));
252 fprintf (file, "[err]");
254 fprintf (file, "[remat]");
260 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
261 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
266 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
267 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
268 /* if assigned to registers */
269 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
273 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
274 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
275 OP_SYMBOL (op)->regs[i]->name :
284 printTypeChain (op->operand.typeOperand, file);
290 fprintf (file, "\n");
295 /*-----------------------------------------------------------------*/
296 /* print functions */
297 /*-----------------------------------------------------------------*/
298 PRINTFUNC (picGetValueAtAddr)
301 printOperand (IC_RESULT (ic), of);
304 printOperand (IC_LEFT (ic), of);
310 PRINTFUNC (picSetValueAtAddr)
314 printOperand (IC_LEFT (ic), of);
315 fprintf (of, "] = ");
316 printOperand (IC_RIGHT (ic), of);
320 PRINTFUNC (picAddrOf)
323 printOperand (IC_RESULT (ic), of);
324 if (IS_ITEMP (IC_LEFT (ic)))
327 fprintf (of, " = &[");
328 printOperand (IC_LEFT (ic), of);
331 if (IS_ITEMP (IC_LEFT (ic)))
332 fprintf (of, " offsetAdd ");
335 printOperand (IC_RIGHT (ic), of);
337 if (IS_ITEMP (IC_LEFT (ic)))
343 PRINTFUNC (picJumpTable)
348 fprintf (of, "%s\t", s);
349 printOperand (IC_JTCOND (ic), of);
351 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
352 sym = setNextItem (IC_JTLABELS (ic)))
353 fprintf (of, "\t\t\t%s\n", sym->name);
356 PRINTFUNC (picGeneric)
359 printOperand (IC_RESULT (ic), of);
361 printOperand (IC_LEFT (ic), of);
362 fprintf (of, " %s ", s);
363 printOperand (IC_RIGHT (ic), of);
367 PRINTFUNC (picGenericOne)
372 printOperand (IC_RESULT (ic), of);
378 fprintf (of, "%s ", s);
379 printOperand (IC_LEFT (ic), of);
382 if (!IC_RESULT (ic) && !IC_LEFT (ic))
391 printOperand (IC_RESULT (ic), of);
393 printOperand (IC_LEFT (ic), of);
394 printOperand (IC_RIGHT (ic), of);
399 PRINTFUNC (picAssign)
403 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
406 printOperand (IC_RESULT (ic), of);
408 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
411 fprintf (of, " %s ", s);
412 printOperand (IC_RIGHT (ic), of);
419 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
425 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
432 printOperand (IC_COND (ic), of);
435 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
438 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
440 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
444 PRINTFUNC (picInline)
446 fprintf (of, "%s", IC_INLINE (ic));
449 PRINTFUNC (picReceive)
451 printOperand (IC_RESULT (ic), of);
452 fprintf (of, " = %s ", s);
453 printOperand (IC_LEFT (ic), of);
457 /*-----------------------------------------------------------------*/
458 /* piCode - prints one iCode */
459 /*-----------------------------------------------------------------*/
461 piCode (void *item, FILE * of)
469 icTab = getTableEntry (ic->op);
470 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
471 ic->filename, ic->lineno,
472 ic->seq, ic->key, ic->depth, ic->supportRtn);
473 icTab->iCodePrint (of, ic, icTab->printName);
479 printiCChain(ic,stdout);
481 /*-----------------------------------------------------------------*/
482 /* printiCChain - prints intermediate code for humans */
483 /*-----------------------------------------------------------------*/
485 printiCChain (iCode * icChain, FILE * of)
492 for (loop = icChain; loop; loop = loop->next)
494 if ((icTab = getTableEntry (loop->op)))
496 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
497 loop->filename, loop->lineno,
498 loop->seq, loop->key, loop->depth, loop->supportRtn);
500 icTab->iCodePrint (of, loop, icTab->printName);
506 /*-----------------------------------------------------------------*/
507 /* newOperand - allocate, init & return a new iCode */
508 /*-----------------------------------------------------------------*/
514 op = Safe_alloc ( sizeof (operand));
520 /*-----------------------------------------------------------------*/
521 /* newiCode - create and return a new iCode entry initialised */
522 /*-----------------------------------------------------------------*/
524 newiCode (int op, operand * left, operand * right)
528 ic = Safe_alloc ( sizeof (iCode));
531 ic->filename = filename;
533 ic->level = scopeLevel;
535 ic->key = iCodeKey++;
537 IC_RIGHT (ic) = right;
542 /*-----------------------------------------------------------------*/
543 /* newiCode for conditional statements */
544 /*-----------------------------------------------------------------*/
546 newiCodeCondition (operand * condition,
552 if (IS_VOID(operandType(condition))) {
553 werror(E_VOID_VALUE_USED);
556 ic = newiCode (IFX, NULL, NULL);
557 IC_COND (ic) = condition;
558 IC_TRUE (ic) = trueLabel;
559 IC_FALSE (ic) = falseLabel;
563 /*-----------------------------------------------------------------*/
564 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
565 /*-----------------------------------------------------------------*/
567 newiCodeLabelGoto (int op, symbol * label)
571 ic = newiCode (op, NULL, NULL);
573 ic->argLabel.label = label;
575 IC_RIGHT (ic) = NULL;
576 IC_RESULT (ic) = NULL;
580 /*-----------------------------------------------------------------*/
581 /* newiTemp - allocate & return a newItemp Variable */
582 /*-----------------------------------------------------------------*/
589 sprintf (buffer, "%s", s);
591 sprintf (buffer, "iTemp%d", iTempNum++);
592 itmp = newSymbol (buffer, 1);
593 strcpy (itmp->rname, itmp->name);
599 /*-----------------------------------------------------------------*/
600 /* newiTempLabel - creates a temp variable label */
601 /*-----------------------------------------------------------------*/
603 newiTempLabel (char *s)
607 /* check if this alredy exists */
608 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
612 itmplbl = newSymbol (s, 1);
615 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
616 itmplbl = newSymbol (buffer, 1);
621 itmplbl->key = labelKey++;
622 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
626 /*-----------------------------------------------------------------*/
627 /* newiTempPreheaderLabel - creates a new preheader label */
628 /*-----------------------------------------------------------------*/
630 newiTempPreheaderLabel ()
634 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
635 itmplbl = newSymbol (buffer, 1);
639 itmplbl->key = labelKey++;
640 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
645 /*-----------------------------------------------------------------*/
646 /* initiCode - initialises some iCode related stuff */
647 /*-----------------------------------------------------------------*/
654 /*-----------------------------------------------------------------*/
655 /* copyiCode - make a copy of the iCode given */
656 /*-----------------------------------------------------------------*/
658 copyiCode (iCode * ic)
660 iCode *nic = newiCode (ic->op, NULL, NULL);
662 nic->lineno = ic->lineno;
663 nic->filename = ic->filename;
664 nic->block = ic->block;
665 nic->level = ic->level;
666 nic->parmBytes = ic->parmBytes;
668 /* deal with the special cases first */
672 IC_COND (nic) = operandFromOperand (IC_COND (ic));
673 IC_TRUE (nic) = IC_TRUE (ic);
674 IC_FALSE (nic) = IC_FALSE (ic);
678 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
679 IC_JTLABELS (nic) = IC_JTLABELS (ic);
684 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
685 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
689 IC_INLINE (nic) = IC_INLINE (ic);
693 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
697 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
698 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
699 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
705 /*-----------------------------------------------------------------*/
706 /* getTableEntry - gets the table entry for the given operator */
707 /*-----------------------------------------------------------------*/
709 getTableEntry (int oper)
713 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
714 if (oper == codeTable[i].icode)
715 return &codeTable[i];
720 /*-----------------------------------------------------------------*/
721 /* newiTempOperand - new intermediate temp operand */
722 /*-----------------------------------------------------------------*/
724 newiTempOperand (sym_link * type, char throwType)
727 operand *op = newOperand ();
731 itmp = newiTemp (NULL);
733 etype = getSpec (type);
735 if (IS_LITERAL (etype))
738 /* copy the type information */
740 itmp->etype = getSpec (itmp->type = (throwType ? type :
741 copyLinkChain (type)));
742 if (IS_LITERAL (itmp->etype))
744 SPEC_SCLS (itmp->etype) = S_REGISTER;
745 SPEC_OCLS (itmp->etype) = reg;
748 op->operand.symOperand = itmp;
749 op->key = itmp->key = ++operandKey;
753 /*-----------------------------------------------------------------*/
754 /* operandType - returns the type chain for an operand */
755 /*-----------------------------------------------------------------*/
757 operandType (operand * op)
759 /* depending on type of operand */
764 return op->operand.valOperand->type;
767 return op->operand.symOperand->type;
770 return op->operand.typeOperand;
772 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
773 " operand type not known ");
774 assert (0); /* should never come here */
775 /* Just to keep the compiler happy */
776 return (sym_link *) 0;
780 /*-----------------------------------------------------------------*/
781 /* isParamterToCall - will return 1 if op is a parameter to args */
782 /*-----------------------------------------------------------------*/
784 isParameterToCall (value * args, operand * op)
791 isSymbolEqual (op->operand.symOperand, tval->sym))
798 /*-----------------------------------------------------------------*/
799 /* isOperandGlobal - return 1 if operand is a global variable */
800 /*-----------------------------------------------------------------*/
802 isOperandGlobal (operand * op)
810 if (op->type == SYMBOL &&
811 (op->operand.symOperand->level == 0 ||
812 IS_STATIC (op->operand.symOperand->etype) ||
813 IS_EXTERN (op->operand.symOperand->etype))
820 /*-----------------------------------------------------------------*/
821 /* isOperandVolatile - return 1 if the operand is volatile */
822 /*-----------------------------------------------------------------*/
824 isOperandVolatile (operand * op, bool chkTemp)
829 if (IS_ITEMP (op) && !chkTemp)
832 opetype = getSpec (optype = operandType (op));
834 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
837 if (IS_VOLATILE (opetype))
842 /*-----------------------------------------------------------------*/
843 /* isOperandLiteral - returns 1 if an operand contains a literal */
844 /*-----------------------------------------------------------------*/
846 isOperandLiteral (operand * op)
853 opetype = getSpec (operandType (op));
855 if (IS_LITERAL (opetype))
860 /*-----------------------------------------------------------------*/
861 /* isOperandInFarSpace - will return true if operand is in farSpace */
862 /*-----------------------------------------------------------------*/
864 isOperandInFarSpace (operand * op)
874 if (!IS_TRUE_SYMOP (op))
877 etype = SPIL_LOC (op)->etype;
883 etype = getSpec (operandType (op));
885 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
888 /*-----------------------------------------------------------------*/
889 /* isOperandOnStack - will return true if operand is on stack */
890 /*-----------------------------------------------------------------*/
892 isOperandOnStack (operand * op)
902 etype = getSpec (operandType (op));
904 return ((IN_STACK (etype)) ? TRUE : FALSE);
907 /*-----------------------------------------------------------------*/
908 /* operandLitValue - literal value of an operand */
909 /*-----------------------------------------------------------------*/
911 operandLitValue (operand * op)
913 assert (isOperandLiteral (op));
915 return floatFromVal (op->operand.valOperand);
918 /*-----------------------------------------------------------------*/
919 /* operandOperation - perforoms operations on operands */
920 /*-----------------------------------------------------------------*/
922 operandOperation (operand * left, operand * right,
923 int op, sym_link * type)
925 sym_link *let , *ret=NULL;
926 operand *retval = (operand *) 0;
928 assert (isOperandLiteral (left));
929 let = getSpec(operandType(left));
931 assert (isOperandLiteral (right));
932 ret = getSpec(operandType(left));
938 retval = operandFromValue (valCastLiteral (type,
939 operandLitValue (left) +
940 operandLitValue (right)));
943 retval = operandFromValue (valCastLiteral (type,
944 operandLitValue (left) -
945 operandLitValue (right)));
948 retval = operandFromValue (valCastLiteral (type,
949 operandLitValue (left) *
950 operandLitValue (right)));
953 if ((unsigned long) operandLitValue (right) == 0)
955 werror (E_DIVIDE_BY_ZERO);
960 retval = operandFromValue (valCastLiteral (type,
961 operandLitValue (left) /
962 operandLitValue (right)));
965 if ((unsigned long) operandLitValue (right) == 0) {
966 werror (E_DIVIDE_BY_ZERO);
970 retval = operandFromLit ((SPEC_USIGN(let) ?
971 (unsigned long) operandLitValue (left) :
972 (long) operandLitValue (left)) %
974 (unsigned long) operandLitValue (right) :
975 (long) operandLitValue (right)));
979 retval = operandFromLit ((SPEC_USIGN(let) ?
980 (unsigned long) operandLitValue (left) :
981 (long) operandLitValue (left)) <<
983 (unsigned long) operandLitValue (right) :
984 (long) operandLitValue (right)));
987 retval = operandFromLit ((SPEC_USIGN(let) ?
988 (unsigned long) operandLitValue (left) :
989 (long) operandLitValue (left)) >>
991 (unsigned long) operandLitValue (right) :
992 (long) operandLitValue (right)));
995 retval = operandFromLit (operandLitValue (left) ==
996 operandLitValue (right));
999 retval = operandFromLit (operandLitValue (left) <
1000 operandLitValue (right));
1003 retval = operandFromLit (operandLitValue (left) <=
1004 operandLitValue (right));
1007 retval = operandFromLit (operandLitValue (left) !=
1008 operandLitValue (right));
1011 retval = operandFromLit (operandLitValue (left) >
1012 operandLitValue (right));
1015 retval = operandFromLit (operandLitValue (left) >=
1016 operandLitValue (right));
1019 retval = operandFromLit ((long)operandLitValue(left) &
1020 (long)operandLitValue(right));
1023 retval = operandFromLit ((long)operandLitValue (left) |
1024 (long)operandLitValue (right));
1027 retval = operandFromLit ((long)operandLitValue (left) ^
1028 (long)operandLitValue (right));
1031 retval = operandFromLit (operandLitValue (left) &&
1032 operandLitValue (right));
1035 retval = operandFromLit (operandLitValue (left) ||
1036 operandLitValue (right));
1040 long i = (long) operandLitValue (left);
1042 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1048 long i = (long) operandLitValue (left);
1050 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1056 retval = operandFromLit (-1 * operandLitValue (left));
1060 retval = operandFromLit (~((long) operandLitValue (left)));
1064 retval = operandFromLit (!operandLitValue (left));
1068 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1069 " operandOperation invalid operator ");
1077 /*-----------------------------------------------------------------*/
1078 /* isOperandEqual - compares two operand & return 1 if they r = */
1079 /*-----------------------------------------------------------------*/
1081 isOperandEqual (operand * left, operand * right)
1083 /* if the pointers are equal then they are equal */
1087 /* if either of them null then false */
1088 if (!left || !right)
1091 if (left->type != right->type)
1094 if (IS_SYMOP (left) && IS_SYMOP (right))
1095 return left->key == right->key;
1097 /* if types are the same */
1101 return isSymbolEqual (left->operand.symOperand,
1102 right->operand.symOperand);
1104 return (floatFromVal (left->operand.valOperand) ==
1105 floatFromVal (right->operand.valOperand));
1107 if (compareType (left->operand.typeOperand,
1108 right->operand.typeOperand) == 1)
1115 /*-------------------------------------------------------------------*/
1116 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1117 /*-------------------------------------------------------------------*/
1119 isiCodeEqual (iCode * left, iCode * right)
1121 /* if the same pointer */
1125 /* if either of them null */
1126 if (!left || !right)
1129 /* if operand are the same */
1130 if (left->op == right->op)
1133 /* compare all the elements depending on type */
1134 if (left->op != IFX)
1136 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1138 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1144 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1146 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1148 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1157 /*-----------------------------------------------------------------*/
1158 /* newiTempFromOp - create a temp Operand with same attributes */
1159 /*-----------------------------------------------------------------*/
1161 newiTempFromOp (operand * op)
1171 nop = newiTempOperand (operandType (op), TRUE);
1172 nop->isaddr = op->isaddr;
1173 nop->isvolatile = op->isvolatile;
1174 nop->isGlobal = op->isGlobal;
1175 nop->isLiteral = op->isLiteral;
1176 nop->usesDefs = op->usesDefs;
1177 nop->isParm = op->isParm;
1181 /*-----------------------------------------------------------------*/
1182 /* operand from operand - creates an operand holder for the type */
1183 /*-----------------------------------------------------------------*/
1185 operandFromOperand (operand * op)
1191 nop = newOperand ();
1192 nop->type = op->type;
1193 nop->isaddr = op->isaddr;
1195 nop->isvolatile = op->isvolatile;
1196 nop->isGlobal = op->isGlobal;
1197 nop->isLiteral = op->isLiteral;
1198 nop->usesDefs = op->usesDefs;
1199 nop->isParm = op->isParm;
1204 nop->operand.symOperand = op->operand.symOperand;
1207 nop->operand.valOperand = op->operand.valOperand;
1210 nop->operand.typeOperand = op->operand.typeOperand;
1217 /*-----------------------------------------------------------------*/
1218 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1219 /*-----------------------------------------------------------------*/
1221 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1223 operand *nop = operandFromOperand (op);
1225 if (nop->type == SYMBOL)
1227 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1228 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1234 /*-----------------------------------------------------------------*/
1235 /* operandFromSymbol - creates an operand from a symbol */
1236 /*-----------------------------------------------------------------*/
1238 operandFromSymbol (symbol * sym)
1243 /* if the symbol's type is a literal */
1244 /* then it is an enumerator type */
1245 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1246 return operandFromValue (valFromType (sym->etype));
1249 sym->key = ++operandKey;
1251 /* if this an implicit variable, means struct/union */
1252 /* member so just return it */
1253 if (sym->implicit || IS_FUNC (sym->type))
1257 op->operand.symOperand = sym;
1259 op->isvolatile = isOperandVolatile (op, TRUE);
1260 op->isGlobal = isOperandGlobal (op);
1264 /* under the following conditions create a
1265 register equivalent for a local symbol */
1266 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1267 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1268 (!(options.model == MODEL_FLAT24)) ) &&
1269 options.stackAuto == 0)
1272 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1273 !IS_FUNC (sym->type) && /* not a function */
1274 !sym->_isparm && /* not a parameter */
1275 sym->level && /* is a local variable */
1276 !sym->addrtaken && /* whose address has not been taken */
1277 !sym->reqv && /* does not already have a reg equivalence */
1278 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1279 !IS_STATIC (sym->etype) && /* and not declared static */
1280 !sym->islbl && /* not a label */
1281 ok && /* farspace check */
1282 !IS_BITVAR (sym->etype) /* not a bit variable */
1286 /* we will use it after all optimizations
1287 and before liveRange calculation */
1288 sym->reqv = newiTempOperand (sym->type, 0);
1289 sym->reqv->key = sym->key;
1290 OP_SYMBOL (sym->reqv)->key = sym->key;
1291 OP_SYMBOL (sym->reqv)->isreqv = 1;
1292 OP_SYMBOL (sym->reqv)->islocal = 1;
1293 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1294 SPIL_LOC (sym->reqv) = sym;
1297 if (!IS_AGGREGATE (sym->type))
1301 op->operand.symOperand = sym;
1304 op->isvolatile = isOperandVolatile (op, TRUE);
1305 op->isGlobal = isOperandGlobal (op);
1306 op->isPtr = IS_PTR (operandType (op));
1307 op->isParm = sym->_isparm;
1312 /* itemp = &[_symbol] */
1314 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1315 IC_LEFT (ic)->type = SYMBOL;
1316 IC_LEFT (ic)->operand.symOperand = sym;
1317 IC_LEFT (ic)->key = sym->key;
1318 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1319 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1320 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1323 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1324 if (IS_ARRAY (sym->type))
1326 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1327 IC_RESULT (ic)->isaddr = 0;
1330 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1334 return IC_RESULT (ic);
1337 /*-----------------------------------------------------------------*/
1338 /* operandFromValue - creates an operand from value */
1339 /*-----------------------------------------------------------------*/
1341 operandFromValue (value * val)
1345 /* if this is a symbol then do the symbol thing */
1347 return operandFromSymbol (val->sym);
1349 /* this is not a symbol */
1352 op->operand.valOperand = val;
1353 op->isLiteral = isOperandLiteral (op);
1357 /*-----------------------------------------------------------------*/
1358 /* operandFromLink - operand from typeChain */
1359 /*-----------------------------------------------------------------*/
1361 operandFromLink (sym_link * type)
1365 /* operand from sym_link */
1371 op->operand.typeOperand = copyLinkChain (type);
1375 /*-----------------------------------------------------------------*/
1376 /* operandFromLit - makes an operand from a literal value */
1377 /*-----------------------------------------------------------------*/
1379 operandFromLit (double i)
1381 return operandFromValue (valueFromLit (i));
1384 /*-----------------------------------------------------------------*/
1385 /* operandFromAst - creates an operand from an ast */
1386 /*-----------------------------------------------------------------*/
1388 operandFromAst (ast * tree,int lvl)
1394 /* depending on type do */
1398 return ast2iCode (tree,lvl+1);
1402 return operandFromValue (tree->opval.val);
1406 return operandFromLink (tree->opval.lnk);
1410 /* Just to keep the comiler happy */
1411 return (operand *) 0;
1414 /*-----------------------------------------------------------------*/
1415 /* setOperandType - sets the operand's type to the given type */
1416 /*-----------------------------------------------------------------*/
1418 setOperandType (operand * op, sym_link * type)
1420 /* depending on the type of operand */
1425 op->operand.valOperand->etype =
1426 getSpec (op->operand.valOperand->type =
1427 copyLinkChain (type));
1431 if (op->operand.symOperand->isitmp)
1432 op->operand.symOperand->etype =
1433 getSpec (op->operand.symOperand->type =
1434 copyLinkChain (type));
1436 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1437 "attempt to modify type of source");
1441 op->operand.typeOperand = copyLinkChain (type);
1446 /*-----------------------------------------------------------------*/
1447 /* Get size in byte of ptr need to access an array */
1448 /*-----------------------------------------------------------------*/
1450 getArraySizePtr (operand * op)
1452 sym_link *ltype = operandType(op);
1456 int size = getSize(ltype);
1457 return(IS_GENPTR(ltype)?(size-1):size);
1462 sym_link *letype = getSpec(ltype);
1463 switch (PTR_TYPE (SPEC_OCLS (letype)))
1475 return (GPTRSIZE-1);
1484 /*-----------------------------------------------------------------*/
1485 /* perform "usual unary conversions" */
1486 /*-----------------------------------------------------------------*/
1488 usualUnaryConversions (operand * op)
1490 if (IS_INTEGRAL (operandType (op)))
1492 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1495 return geniCodeCast (INTTYPE, op, TRUE);
1501 /*-----------------------------------------------------------------*/
1502 /* perform "usual binary conversions" */
1503 /*-----------------------------------------------------------------*/
1505 usualBinaryConversions (operand ** op1, operand ** op2)
1508 sym_link *rtype = operandType (*op2);
1509 sym_link *ltype = operandType (*op1);
1511 ctype = computeType (ltype, rtype);
1512 *op1 = geniCodeCast (ctype, *op1, TRUE);
1513 *op2 = geniCodeCast (ctype, *op2, TRUE);
1518 /*-----------------------------------------------------------------*/
1519 /* geniCodeValueAtAddress - generate intermeditate code for value */
1521 /*-----------------------------------------------------------------*/
1523 geniCodeRValue (operand * op, bool force)
1526 sym_link *type = operandType (op);
1527 sym_link *etype = getSpec (type);
1529 /* if this is an array & already */
1530 /* an address then return this */
1531 if (IS_AGGREGATE (type) ||
1532 (IS_PTR (type) && !force && !op->isaddr))
1533 return operandFromOperand (op);
1535 /* if this is not an address then must be */
1536 /* rvalue already so return this one */
1540 /* if this is not a temp symbol then */
1541 if (!IS_ITEMP (op) &&
1543 !IN_FARSPACE (SPEC_OCLS (etype)))
1545 op = operandFromOperand (op);
1550 if (IS_SPEC (type) &&
1551 IS_TRUE_SYMOP (op) &&
1552 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1553 /* TARGET_IS_DS390)) */
1554 (options.model == MODEL_FLAT24) ))
1556 op = operandFromOperand (op);
1561 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1562 if (IS_PTR (type) && op->isaddr && force)
1565 type = copyLinkChain (type);
1567 IC_RESULT (ic) = newiTempOperand (type, 1);
1568 IC_RESULT (ic)->isaddr = 0;
1570 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1574 return IC_RESULT (ic);
1577 /*-----------------------------------------------------------------*/
1578 /* geniCodeCast - changes the value from one type to another */
1579 /*-----------------------------------------------------------------*/
1581 geniCodeCast (sym_link * type, operand * op, bool implicit)
1585 sym_link *opetype = getSpec (optype = operandType (op));
1589 /* one of them has size zero then error */
1590 if (IS_VOID (optype))
1592 werror (E_CAST_ZERO);
1596 /* if the operand is already the desired type then do nothing */
1597 if (compareType (type, optype) == 1)
1600 /* if this is a literal then just change the type & return */
1601 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1602 return operandFromValue (valCastLiteral (type,
1603 operandLitValue (op)));
1605 /* if casting to/from pointers, do some checking */
1606 if (IS_PTR(type)) { // to a pointer
1607 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1608 if (IS_INTEGRAL(optype)) {
1609 // maybe this is NULL, than it's ok.
1610 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1611 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1612 // no way to set the storage
1613 if (IS_LITERAL(optype)) {
1614 werror(E_LITERAL_GENERIC);
1617 werror(E_NONPTR2_GENPTR);
1620 } else if (implicit) {
1621 werror(W_INTEGRAL2PTR_NOCAST);
1626 // shouldn't do that with float, array or structure unless to void
1627 if (!IS_VOID(getSpec(type)) &&
1628 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1629 werror(E_INCOMPAT_TYPES);
1633 } else { // from a pointer to a pointer
1634 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1635 // if not a pointer to a function
1636 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1637 if (implicit) { // if not to generic, they have to match
1638 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1639 werror(E_INCOMPAT_PTYPES);
1646 } else { // to a non pointer
1647 if (IS_PTR(optype)) { // from a pointer
1648 if (implicit) { // sneaky
1649 if (IS_INTEGRAL(type)) {
1650 werror(W_PTR2INTEGRAL_NOCAST);
1652 } else { // shouldn't do that with float, array or structure
1653 werror(E_INCOMPAT_TYPES);
1660 printFromToType (optype, type);
1663 /* if they are the same size create an assignment */
1664 if (getSize (type) == getSize (optype) &&
1665 !IS_BITFIELD (type) &&
1667 !IS_FLOAT (optype) &&
1668 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1669 (!IS_SPEC (type) && !IS_SPEC (optype))))
1672 ic = newiCode ('=', NULL, op);
1673 IC_RESULT (ic) = newiTempOperand (type, 0);
1674 SPIL_LOC (IC_RESULT (ic)) =
1675 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1676 IC_RESULT (ic)->isaddr = 0;
1680 ic = newiCode (CAST, operandFromLink (type),
1681 geniCodeRValue (op, FALSE));
1683 IC_RESULT (ic) = newiTempOperand (type, 0);
1686 /* preserve the storage class & output class */
1687 /* of the original variable */
1688 restype = getSpec (operandType (IC_RESULT (ic)));
1689 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1690 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1693 return IC_RESULT (ic);
1696 /*-----------------------------------------------------------------*/
1697 /* geniCodeLabel - will create a Label */
1698 /*-----------------------------------------------------------------*/
1700 geniCodeLabel (symbol * label)
1704 ic = newiCodeLabelGoto (LABEL, label);
1708 /*-----------------------------------------------------------------*/
1709 /* geniCodeGoto - will create a Goto */
1710 /*-----------------------------------------------------------------*/
1712 geniCodeGoto (symbol * label)
1716 ic = newiCodeLabelGoto (GOTO, label);
1720 /*-----------------------------------------------------------------*/
1721 /* geniCodeMultiply - gen intermediate code for multiplication */
1722 /*-----------------------------------------------------------------*/
1724 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1731 /* if they are both literal then we know the result */
1732 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1733 return operandFromValue (valMult (left->operand.valOperand,
1734 right->operand.valOperand));
1736 if (IS_LITERAL(retype)) {
1737 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1740 resType = usualBinaryConversions (&left, &right);
1742 rtype = operandType (right);
1743 retype = getSpec (rtype);
1744 ltype = operandType (left);
1745 letype = getSpec (ltype);
1749 SPEC_NOUN(getSpec(resType))=V_INT;
1752 /* if the right is a literal & power of 2 */
1753 /* then make it a left shift */
1754 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1755 efficient in most cases than 2 bytes result = 2 bytes << literal
1756 if port has 1 byte muldiv */
1757 if (p2 && !IS_FLOAT (letype) &&
1758 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1759 (port->support.muldiv == 1)))
1761 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1763 /* LEFT_OP need same size for left and result, */
1764 left = geniCodeCast (resType, left, TRUE);
1765 ltype = operandType (left);
1767 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1771 ic = newiCode ('*', left, right); /* normal multiplication */
1772 /* if the size left or right > 1 then support routine */
1773 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1777 IC_RESULT (ic) = newiTempOperand (resType, 1);
1780 return IC_RESULT (ic);
1783 /*-----------------------------------------------------------------*/
1784 /* geniCodeDivision - gen intermediate code for division */
1785 /*-----------------------------------------------------------------*/
1787 geniCodeDivision (operand * left, operand * right)
1792 sym_link *rtype = operandType (right);
1793 sym_link *retype = getSpec (rtype);
1794 sym_link *ltype = operandType (left);
1795 sym_link *letype = getSpec (ltype);
1797 resType = usualBinaryConversions (&left, &right);
1799 /* if the right is a literal & power of 2 */
1800 /* then make it a right shift */
1801 if (IS_LITERAL (retype) &&
1802 !IS_FLOAT (letype) &&
1803 (p2 = powof2 ((unsigned long)
1804 floatFromVal (right->operand.valOperand)))) {
1805 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1809 ic = newiCode ('/', left, right); /* normal division */
1810 /* if the size left or right > 1 then support routine */
1811 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1814 IC_RESULT (ic) = newiTempOperand (resType, 0);
1817 return IC_RESULT (ic);
1819 /*-----------------------------------------------------------------*/
1820 /* geniCodeModulus - gen intermediate code for modulus */
1821 /*-----------------------------------------------------------------*/
1823 geniCodeModulus (operand * left, operand * right)
1829 /* if they are both literal then we know the result */
1830 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1831 return operandFromValue (valMod (left->operand.valOperand,
1832 right->operand.valOperand));
1834 resType = usualBinaryConversions (&left, &right);
1836 /* now they are the same size */
1837 ic = newiCode ('%', left, right);
1839 /* if the size left or right > 1 then support routine */
1840 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1842 IC_RESULT (ic) = newiTempOperand (resType, 0);
1845 return IC_RESULT (ic);
1848 /*-----------------------------------------------------------------*/
1849 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1850 /*-----------------------------------------------------------------*/
1852 geniCodePtrPtrSubtract (operand * left, operand * right)
1858 /* if they are both literals then */
1859 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1861 result = operandFromValue (valMinus (left->operand.valOperand,
1862 right->operand.valOperand));
1866 ic = newiCode ('-', left, right);
1868 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1872 return geniCodeDivision (result,
1873 operandFromLit (getSize (ltype->next)));
1876 /*-----------------------------------------------------------------*/
1877 /* geniCodeSubtract - generates code for subtraction */
1878 /*-----------------------------------------------------------------*/
1880 geniCodeSubtract (operand * left, operand * right)
1887 /* if they both pointers then */
1888 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1889 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1890 return geniCodePtrPtrSubtract (left, right);
1892 /* if they are both literal then we know the result */
1893 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1894 && left->isLiteral && right->isLiteral)
1895 return operandFromValue (valMinus (left->operand.valOperand,
1896 right->operand.valOperand));
1898 /* if left is an array or pointer */
1899 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1901 isarray = left->isaddr;
1902 right = geniCodeMultiply (right,
1903 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1904 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1907 { /* make them the same size */
1908 resType = usualBinaryConversions (&left, &right);
1911 ic = newiCode ('-', left, right);
1913 IC_RESULT (ic) = newiTempOperand (resType, 1);
1914 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1916 /* if left or right is a float */
1917 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1921 return IC_RESULT (ic);
1924 /*-----------------------------------------------------------------*/
1925 /* geniCodeAdd - generates iCode for addition */
1926 /*-----------------------------------------------------------------*/
1928 geniCodeAdd (operand * left, operand * right,int lvl)
1936 /* if left is an array then array access */
1937 if (IS_ARRAY (ltype))
1938 return geniCodeArray (left, right,lvl);
1940 /* if the right side is LITERAL zero */
1941 /* return the left side */
1942 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1945 /* if left is literal zero return right */
1946 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1949 /* if left is an array or pointer then size */
1952 isarray = left->isaddr;
1953 // there is no need to multiply with 1
1954 if (getSize(ltype->next)!=1) {
1955 size = operandFromLit (getSize (ltype->next));
1956 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1958 resType = copyLinkChain (ltype);
1961 { /* make them the same size */
1962 resType = usualBinaryConversions (&left, &right);
1965 /* if they are both literals then we know */
1966 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1967 && left->isLiteral && right->isLiteral)
1968 return operandFromValue (valPlus (valFromType (letype),
1969 valFromType (retype)));
1971 ic = newiCode ('+', left, right);
1973 IC_RESULT (ic) = newiTempOperand (resType, 1);
1974 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1976 /* if left or right is a float then support
1978 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1983 return IC_RESULT (ic);
1987 /*-----------------------------------------------------------------*/
1988 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1989 /*-----------------------------------------------------------------*/
1991 aggrToPtr (sym_link * type, bool force)
1997 if (IS_PTR (type) && !force)
2000 etype = getSpec (type);
2004 /* if the output class is generic */
2005 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2006 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2008 /* if the variable was declared a constant */
2009 /* then the pointer points to a constant */
2010 if (IS_CONSTANT (etype))
2011 DCL_PTR_CONST (ptype) = 1;
2013 /* the variable was volatile then pointer to volatile */
2014 if (IS_VOLATILE (etype))
2015 DCL_PTR_VOLATILE (ptype) = 1;
2019 /*-----------------------------------------------------------------*/
2020 /* geniCodeArray2Ptr - array to pointer */
2021 /*-----------------------------------------------------------------*/
2023 geniCodeArray2Ptr (operand * op)
2025 sym_link *optype = operandType (op);
2026 sym_link *opetype = getSpec (optype);
2028 /* set the pointer depending on the storage class */
2029 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2030 DCL_PTR_CONST (optype) = port->mem.code_ro;
2033 /* if the variable was declared a constant */
2034 /* then the pointer points to a constant */
2035 if (IS_CONSTANT (opetype))
2036 DCL_PTR_CONST (optype) = 1;
2038 /* the variable was volatile then pointer to volatile */
2039 if (IS_VOLATILE (opetype))
2040 DCL_PTR_VOLATILE (optype) = 1;
2046 /*-----------------------------------------------------------------*/
2047 /* geniCodeArray - array access */
2048 /*-----------------------------------------------------------------*/
2050 geniCodeArray (operand * left, operand * right,int lvl)
2053 sym_link *ltype = operandType (left);
2057 if (IS_PTR (ltype->next) && left->isaddr)
2059 left = geniCodeRValue (left, FALSE);
2061 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2064 right = geniCodeMultiply (right,
2065 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2067 /* we can check for limits here */
2068 if (isOperandLiteral (right) &&
2071 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2073 werror (E_ARRAY_BOUND);
2074 right = operandFromLit (0);
2077 ic = newiCode ('+', left, right);
2079 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2080 !IS_AGGREGATE (ltype->next) &&
2081 !IS_PTR (ltype->next))
2082 ? ltype : ltype->next), 0);
2084 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2086 return IC_RESULT (ic);
2089 /*-----------------------------------------------------------------*/
2090 /* geniCodeStruct - generates intermediate code for structres */
2091 /*-----------------------------------------------------------------*/
2093 geniCodeStruct (operand * left, operand * right, bool islval)
2096 sym_link *type = operandType (left);
2097 sym_link *etype = getSpec (type);
2099 symbol *element = getStructElement (SPEC_STRUCT (etype),
2100 right->operand.symOperand);
2102 /* add the offset */
2103 ic = newiCode ('+', left, operandFromLit (element->offset));
2105 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2107 /* preserve the storage & output class of the struct */
2108 /* as well as the volatile attribute */
2109 retype = getSpec (operandType (IC_RESULT (ic)));
2110 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2111 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2112 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2114 if (IS_PTR (element->type))
2115 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2117 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2121 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2124 /*-----------------------------------------------------------------*/
2125 /* geniCodePostInc - generate int code for Post increment */
2126 /*-----------------------------------------------------------------*/
2128 geniCodePostInc (operand * op)
2132 sym_link *optype = operandType (op);
2134 operand *rv = (IS_ITEMP (op) ?
2135 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2137 sym_link *rvtype = operandType (rv);
2140 /* if this is not an address we have trouble */
2143 werror (E_LVALUE_REQUIRED, "++");
2147 rOp = newiTempOperand (rvtype, 0);
2148 OP_SYMBOL(rOp)->noSpilLoc = 1;
2151 OP_SYMBOL(rv)->noSpilLoc = 1;
2153 geniCodeAssign (rOp, rv, 0);
2155 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2156 if (IS_FLOAT (rvtype))
2157 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2159 ic = newiCode ('+', rv, operandFromLit (size));
2161 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2164 geniCodeAssign (op, result, 0);
2170 /*-----------------------------------------------------------------*/
2171 /* geniCodePreInc - generate code for preIncrement */
2172 /*-----------------------------------------------------------------*/
2174 geniCodePreInc (operand * op)
2177 sym_link *optype = operandType (op);
2178 operand *rop = (IS_ITEMP (op) ?
2179 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2181 sym_link *roptype = operandType (rop);
2187 werror (E_LVALUE_REQUIRED, "++");
2192 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2193 if (IS_FLOAT (roptype))
2194 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2196 ic = newiCode ('+', rop, operandFromLit (size));
2197 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2201 return geniCodeAssign (op, result, 0);
2204 /*-----------------------------------------------------------------*/
2205 /* geniCodePostDec - generates code for Post decrement */
2206 /*-----------------------------------------------------------------*/
2208 geniCodePostDec (operand * op)
2212 sym_link *optype = operandType (op);
2214 operand *rv = (IS_ITEMP (op) ?
2215 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2217 sym_link *rvtype = operandType (rv);
2220 /* if this is not an address we have trouble */
2223 werror (E_LVALUE_REQUIRED, "--");
2227 rOp = newiTempOperand (rvtype, 0);
2228 OP_SYMBOL(rOp)->noSpilLoc = 1;
2231 OP_SYMBOL(rv)->noSpilLoc = 1;
2233 geniCodeAssign (rOp, rv, 0);
2235 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2236 if (IS_FLOAT (rvtype))
2237 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2239 ic = newiCode ('-', rv, operandFromLit (size));
2241 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2244 geniCodeAssign (op, result, 0);
2250 /*-----------------------------------------------------------------*/
2251 /* geniCodePreDec - generate code for pre decrement */
2252 /*-----------------------------------------------------------------*/
2254 geniCodePreDec (operand * op)
2257 sym_link *optype = operandType (op);
2258 operand *rop = (IS_ITEMP (op) ?
2259 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2261 sym_link *roptype = operandType (rop);
2267 werror (E_LVALUE_REQUIRED, "--");
2272 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2273 if (IS_FLOAT (roptype))
2274 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2276 ic = newiCode ('-', rop, operandFromLit (size));
2277 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2281 return geniCodeAssign (op, result, 0);
2285 /*-----------------------------------------------------------------*/
2286 /* geniCodeBitwise - gen int code for bitWise operators */
2287 /*-----------------------------------------------------------------*/
2289 geniCodeBitwise (operand * left, operand * right,
2290 int oper, sym_link * resType)
2294 // bitwise operations must be done unsigned
2295 // WHY ? causes very bad things to happen with CSE
2296 // SPEC_USIGN(resType)=1;
2298 left = geniCodeCast (resType, left, TRUE);
2299 right = geniCodeCast (resType, right, TRUE);
2301 ic = newiCode (oper, left, right);
2302 IC_RESULT (ic) = newiTempOperand (resType, 0);
2305 return IC_RESULT (ic);
2308 /*-----------------------------------------------------------------*/
2309 /* geniCodeAddressOf - gens icode for '&' address of operator */
2310 /*-----------------------------------------------------------------*/
2312 geniCodeAddressOf (operand * op)
2316 sym_link *optype = operandType (op);
2317 sym_link *opetype = getSpec (optype);
2319 /* lvalue check already done in decorateType */
2320 /* this must be a lvalue */
2321 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2322 /* werror (E_LVALUE_REQUIRED,"&"); */
2327 p->class = DECLARATOR;
2329 /* set the pointer depending on the storage class */
2330 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2331 DCL_PTR_CONST (p) = port->mem.code_ro;
2333 /* make sure we preserve the const & volatile */
2334 if (IS_CONSTANT (opetype))
2335 DCL_PTR_CONST (p) = 1;
2337 if (IS_VOLATILE (opetype))
2338 DCL_PTR_VOLATILE (p) = 1;
2340 p->next = copyLinkChain (optype);
2342 /* if already a temp */
2345 setOperandType (op, p);
2350 /* other wise make this of the type coming in */
2351 ic = newiCode (ADDRESS_OF, op, NULL);
2352 IC_RESULT (ic) = newiTempOperand (p, 1);
2353 IC_RESULT (ic)->isaddr = 0;
2355 return IC_RESULT (ic);
2357 /*-----------------------------------------------------------------*/
2358 /* setOClass - sets the output class depending on the pointer type */
2359 /*-----------------------------------------------------------------*/
2361 setOClass (sym_link * ptr, sym_link * spec)
2363 switch (DCL_TYPE (ptr))
2366 SPEC_OCLS (spec) = data;
2370 SPEC_OCLS (spec) = generic;
2374 SPEC_OCLS (spec) = xdata;
2378 SPEC_OCLS (spec) = code;
2382 SPEC_OCLS (spec) = idata;
2386 SPEC_OCLS (spec) = xstack;
2390 SPEC_OCLS (spec) = eeprom;
2399 /*-----------------------------------------------------------------*/
2400 /* geniCodeDerefPtr - dereference pointer with '*' */
2401 /*-----------------------------------------------------------------*/
2403 geniCodeDerefPtr (operand * op,int lvl)
2405 sym_link *rtype, *retype;
2406 sym_link *optype = operandType (op);
2408 /* if this is a pointer then generate the rvalue */
2409 if (IS_PTR (optype))
2411 if (IS_TRUE_SYMOP (op))
2414 op = geniCodeRValue (op, TRUE);
2417 op = geniCodeRValue (op, TRUE);
2420 /* now get rid of the pointer part */
2421 if (isLvaluereq(lvl) && IS_ITEMP (op))
2423 retype = getSpec (rtype = copyLinkChain (optype));
2427 retype = getSpec (rtype = copyLinkChain (optype->next));
2430 /* if this is a pointer then outputclass needs 2b updated */
2431 if (IS_PTR (optype))
2432 setOClass (optype, retype);
2434 op->isGptr = IS_GENPTR (optype);
2436 /* if the pointer was declared as a constant */
2437 /* then we cannot allow assignment to the derefed */
2438 if (IS_PTR_CONST (optype))
2439 SPEC_CONST (retype) = 1;
2441 op->isaddr = (IS_PTR (rtype) ||
2442 IS_STRUCT (rtype) ||
2447 if (!isLvaluereq(lvl))
2448 op = geniCodeRValue (op, TRUE);
2450 setOperandType (op, rtype);
2455 /*-----------------------------------------------------------------*/
2456 /* geniCodeUnaryMinus - does a unary minus of the operand */
2457 /*-----------------------------------------------------------------*/
2459 geniCodeUnaryMinus (operand * op)
2462 sym_link *optype = operandType (op);
2464 if (IS_LITERAL (optype))
2465 return operandFromLit (-floatFromVal (op->operand.valOperand));
2467 ic = newiCode (UNARYMINUS, op, NULL);
2468 IC_RESULT (ic) = newiTempOperand (optype, 0);
2470 return IC_RESULT (ic);
2473 /*-----------------------------------------------------------------*/
2474 /* geniCodeLeftShift - gen i code for left shift */
2475 /*-----------------------------------------------------------------*/
2477 geniCodeLeftShift (operand * left, operand * right)
2481 ic = newiCode (LEFT_OP, left, right);
2482 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2484 return IC_RESULT (ic);
2487 /*-----------------------------------------------------------------*/
2488 /* geniCodeRightShift - gen i code for right shift */
2489 /*-----------------------------------------------------------------*/
2491 geniCodeRightShift (operand * left, operand * right)
2495 ic = newiCode (RIGHT_OP, left, right);
2496 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2498 return IC_RESULT (ic);
2501 /*-----------------------------------------------------------------*/
2502 /* geniCodeLogic- logic code */
2503 /*-----------------------------------------------------------------*/
2505 geniCodeLogic (operand * left, operand * right, int op)
2509 sym_link *rtype = operandType (right);
2510 sym_link *ltype = operandType (left);
2512 /* left is integral type and right is literal then
2513 check if the literal value is within bounds */
2514 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2516 checkConstantRange(ltype,
2517 OP_VALUE(right), "compare operation", 1);
2520 ctype = usualBinaryConversions (&left, &right);
2522 ic = newiCode (op, left, right);
2523 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2525 /* if comparing float
2526 and not a '==' || '!=' || '&&' || '||' (these
2528 if (IS_FLOAT(ctype) &&
2536 return IC_RESULT (ic);
2539 /*-----------------------------------------------------------------*/
2540 /* geniCodeUnary - for a a generic unary operation */
2541 /*-----------------------------------------------------------------*/
2543 geniCodeUnary (operand * op, int oper)
2545 iCode *ic = newiCode (oper, op, NULL);
2547 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2549 return IC_RESULT (ic);
2552 /*-----------------------------------------------------------------*/
2553 /* geniCodeConditional - geniCode for '?' ':' operation */
2554 /*-----------------------------------------------------------------*/
2556 geniCodeConditional (ast * tree,int lvl)
2559 symbol *falseLabel = newiTempLabel (NULL);
2560 symbol *exitLabel = newiTempLabel (NULL);
2561 operand *cond = ast2iCode (tree->left,lvl+1);
2562 operand *true, *false, *result;
2564 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2568 true = ast2iCode (tree->right->left,lvl+1);
2570 /* move the value to a new Operand */
2571 result = newiTempOperand (operandType (true), 0);
2572 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2574 /* generate an unconditional goto */
2575 geniCodeGoto (exitLabel);
2577 /* now for the right side */
2578 geniCodeLabel (falseLabel);
2580 false = ast2iCode (tree->right->right,lvl+1);
2581 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2583 /* create the exit label */
2584 geniCodeLabel (exitLabel);
2589 /*-----------------------------------------------------------------*/
2590 /* geniCodeAssign - generate code for assignment */
2591 /*-----------------------------------------------------------------*/
2593 geniCodeAssign (operand * left, operand * right, int nosupdate)
2596 sym_link *ltype = operandType (left);
2597 sym_link *rtype = operandType (right);
2599 if (!left->isaddr && !IS_ITEMP (left))
2601 werror (E_LVALUE_REQUIRED, "assignment");
2605 /* left is integral type and right is literal then
2606 check if the literal value is within bounds */
2607 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2609 checkConstantRange(ltype,
2610 OP_VALUE(right), "= operation", 0);
2613 /* if the left & right type don't exactly match */
2614 /* if pointer set then make sure the check is
2615 done with the type & not the pointer */
2616 /* then cast rights type to left */
2618 /* first check the type for pointer assignement */
2619 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2620 compareType (ltype, rtype) <= 0)
2622 if (compareType (ltype->next, rtype) < 0)
2623 right = geniCodeCast (ltype->next, right, TRUE);
2625 else if (compareType (ltype, rtype) < 0)
2626 right = geniCodeCast (ltype, right, TRUE);
2628 /* if left is a true symbol & ! volatile
2629 create an assignment to temporary for
2630 the right & then assign this temporary
2631 to the symbol this is SSA . isn't it simple
2632 and folks have published mountains of paper on it */
2633 if (IS_TRUE_SYMOP (left) &&
2634 !isOperandVolatile (left, FALSE) &&
2635 isOperandGlobal (left))
2639 if (IS_TRUE_SYMOP (right))
2640 sym = OP_SYMBOL (right);
2641 ic = newiCode ('=', NULL, right);
2642 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2643 SPIL_LOC (right) = sym;
2647 ic = newiCode ('=', NULL, right);
2648 IC_RESULT (ic) = left;
2651 /* if left isgptr flag is set then support
2652 routine will be required */
2656 ic->nosupdate = nosupdate;
2660 /*-----------------------------------------------------------------*/
2661 /* geniCodeSEParms - generate code for side effecting fcalls */
2662 /*-----------------------------------------------------------------*/
2664 geniCodeSEParms (ast * parms,int lvl)
2669 if (parms->type == EX_OP && parms->opval.op == PARAM)
2671 geniCodeSEParms (parms->left,lvl);
2672 geniCodeSEParms (parms->right,lvl);
2676 /* hack don't like this but too lazy to think of
2678 if (IS_ADDRESS_OF_OP (parms))
2679 parms->left->lvalue = 1;
2681 if (IS_CAST_OP (parms) &&
2682 IS_PTR (parms->ftype) &&
2683 IS_ADDRESS_OF_OP (parms->right))
2684 parms->right->left->lvalue = 1;
2686 parms->opval.oprnd =
2687 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2689 parms->type = EX_OPERAND;
2692 /*-----------------------------------------------------------------*/
2693 /* geniCodeParms - generates parameters */
2694 /*-----------------------------------------------------------------*/
2696 geniCodeParms (ast * parms, value *argVals, int *stack,
2697 sym_link * fetype, symbol * func,int lvl)
2705 if (argVals==NULL) {
2707 argVals=FUNC_ARGS(func->type);
2710 /* if this is a param node then do the left & right */
2711 if (parms->type == EX_OP && parms->opval.op == PARAM)
2713 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2714 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2718 /* get the parameter value */
2719 if (parms->type == EX_OPERAND)
2720 pval = parms->opval.oprnd;
2723 /* maybe this else should go away ?? */
2724 /* hack don't like this but too lazy to think of
2726 if (IS_ADDRESS_OF_OP (parms))
2727 parms->left->lvalue = 1;
2729 if (IS_CAST_OP (parms) &&
2730 IS_PTR (parms->ftype) &&
2731 IS_ADDRESS_OF_OP (parms->right))
2732 parms->right->left->lvalue = 1;
2734 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2737 /* if register parm then make it a send */
2738 if (IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type))
2740 ic = newiCode (SEND, pval, NULL);
2745 /* now decide whether to push or assign */
2746 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2750 operand *top = operandFromSymbol (argVals->sym);
2751 geniCodeAssign (top, pval, 1);
2755 sym_link *p = operandType (pval);
2757 ic = newiCode (IPUSH, pval, NULL);
2759 /* update the stack adjustment */
2760 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2765 argVals=argVals->next;
2769 /*-----------------------------------------------------------------*/
2770 /* geniCodeCall - generates temp code for calling */
2771 /*-----------------------------------------------------------------*/
2773 geniCodeCall (operand * left, ast * parms,int lvl)
2777 sym_link *type, *etype;
2780 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2781 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2782 werror (E_FUNCTION_EXPECTED);
2786 /* take care of parameters with side-effecting
2787 function calls in them, this is required to take care
2788 of overlaying function parameters */
2789 geniCodeSEParms (parms,lvl);
2791 /* first the parameters */
2792 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2794 /* now call : if symbol then pcall */
2795 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2796 ic = newiCode (PCALL, left, NULL);
2798 ic = newiCode (CALL, left, NULL);
2800 type = copyLinkChain (operandType (left)->next);
2801 etype = getSpec (type);
2802 SPEC_EXTR (etype) = 0;
2803 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2807 /* stack adjustment after call */
2808 ic->parmBytes = stack;
2813 /*-----------------------------------------------------------------*/
2814 /* geniCodeReceive - generate intermediate code for "receive" */
2815 /*-----------------------------------------------------------------*/
2817 geniCodeReceive (value * args)
2819 /* for all arguments that are passed in registers */
2823 if (IS_REGPARM (args->etype))
2825 operand *opr = operandFromValue (args);
2827 symbol *sym = OP_SYMBOL (opr);
2830 /* we will use it after all optimizations
2831 and before liveRange calculation */
2832 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2835 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2836 options.stackAuto == 0 &&
2837 /* !TARGET_IS_DS390) */
2838 (!(options.model == MODEL_FLAT24)) )
2843 opl = newiTempOperand (args->type, 0);
2845 sym->reqv->key = sym->key;
2846 OP_SYMBOL (sym->reqv)->key = sym->key;
2847 OP_SYMBOL (sym->reqv)->isreqv = 1;
2848 OP_SYMBOL (sym->reqv)->islocal = 0;
2849 SPIL_LOC (sym->reqv) = sym;
2853 ic = newiCode (RECEIVE, NULL, NULL);
2854 currFunc->recvSize = getSize (sym->etype);
2855 IC_RESULT (ic) = opr;
2863 /*-----------------------------------------------------------------*/
2864 /* geniCodeFunctionBody - create the function body */
2865 /*-----------------------------------------------------------------*/
2867 geniCodeFunctionBody (ast * tree,int lvl)
2874 /* reset the auto generation */
2880 func = ast2iCode (tree->left,lvl+1);
2881 fetype = getSpec (operandType (func));
2883 savelineno = lineno;
2884 lineno = OP_SYMBOL (func)->lineDef;
2885 /* create an entry label */
2886 geniCodeLabel (entryLabel);
2887 lineno = savelineno;
2889 /* create a proc icode */
2890 ic = newiCode (FUNCTION, func, NULL);
2891 ic->lineno = OP_SYMBOL (func)->lineDef;
2895 /* for all parameters that are passed
2896 on registers add a "receive" */
2897 geniCodeReceive (tree->values.args);
2899 /* generate code for the body */
2900 ast2iCode (tree->right,lvl+1);
2902 /* create a label for return */
2903 geniCodeLabel (returnLabel);
2905 /* now generate the end proc */
2906 ic = newiCode (ENDFUNCTION, func, NULL);
2911 /*-----------------------------------------------------------------*/
2912 /* geniCodeReturn - gen icode for 'return' statement */
2913 /*-----------------------------------------------------------------*/
2915 geniCodeReturn (operand * op)
2919 /* if the operand is present force an rvalue */
2921 op = geniCodeRValue (op, FALSE);
2923 ic = newiCode (RETURN, op, NULL);
2927 /*-----------------------------------------------------------------*/
2928 /* geniCodeIfx - generates code for extended if statement */
2929 /*-----------------------------------------------------------------*/
2931 geniCodeIfx (ast * tree,int lvl)
2934 operand *condition = ast2iCode (tree->left,lvl+1);
2937 /* if condition is null then exit */
2941 condition = geniCodeRValue (condition, FALSE);
2943 cetype = getSpec (operandType (condition));
2944 /* if the condition is a literal */
2945 if (IS_LITERAL (cetype))
2947 if (floatFromVal (condition->operand.valOperand))
2949 if (tree->trueLabel)
2950 geniCodeGoto (tree->trueLabel);
2956 if (tree->falseLabel)
2957 geniCodeGoto (tree->falseLabel);
2964 if (tree->trueLabel)
2966 ic = newiCodeCondition (condition,
2971 if (tree->falseLabel)
2972 geniCodeGoto (tree->falseLabel);
2976 ic = newiCodeCondition (condition,
2983 ast2iCode (tree->right,lvl+1);
2986 /*-----------------------------------------------------------------*/
2987 /* geniCodeJumpTable - tries to create a jump table for switch */
2988 /*-----------------------------------------------------------------*/
2990 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
2992 int min = 0, max = 0, t, cnt = 0;
2999 if (!tree || !caseVals)
3002 /* the criteria for creating a jump table is */
3003 /* all integer numbers between the maximum & minimum must */
3004 /* be present , the maximum value should not exceed 255 */
3005 min = max = (int) floatFromVal (vch = caseVals);
3006 sprintf (buffer, "_case_%d_%d",
3007 tree->values.switchVals.swNum,
3009 addSet (&labels, newiTempLabel (buffer));
3011 /* if there is only one case value then no need */
3012 if (!(vch = vch->next))
3017 if (((t = (int) floatFromVal (vch)) - max) != 1)
3019 sprintf (buffer, "_case_%d_%d",
3020 tree->values.switchVals.swNum,
3022 addSet (&labels, newiTempLabel (buffer));
3028 /* if the number of case statements <= 2 then */
3029 /* it is not economical to create the jump table */
3030 /* since two compares are needed for boundary conditions */
3031 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3034 if (tree->values.switchVals.swDefault)
3035 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3037 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3039 falseLabel = newiTempLabel (buffer);
3041 /* so we can create a jumptable */
3042 /* first we rule out the boundary conditions */
3043 /* if only optimization says so */
3044 if (!optimize.noJTabBoundary)
3046 sym_link *cetype = getSpec (operandType (cond));
3047 /* no need to check the lower bound if
3048 the condition is unsigned & minimum value is zero */
3049 if (!(min == 0 && SPEC_USIGN (cetype)))
3051 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3052 ic = newiCodeCondition (boundary, falseLabel, NULL);
3056 /* now for upper bounds */
3057 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3058 ic = newiCodeCondition (boundary, falseLabel, NULL);
3062 /* if the min is not zero then we no make it zero */
3065 cond = geniCodeSubtract (cond, operandFromLit (min));
3066 setOperandType (cond, UCHARTYPE);
3069 /* now create the jumptable */
3070 ic = newiCode (JUMPTABLE, NULL, NULL);
3071 IC_JTCOND (ic) = cond;
3072 IC_JTLABELS (ic) = labels;
3077 /*-----------------------------------------------------------------*/
3078 /* geniCodeSwitch - changes a switch to a if statement */
3079 /*-----------------------------------------------------------------*/
3081 geniCodeSwitch (ast * tree,int lvl)
3084 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3085 value *caseVals = tree->values.switchVals.swVals;
3086 symbol *trueLabel, *falseLabel;
3088 /* if we can make this a jump table */
3089 if (geniCodeJumpTable (cond, caseVals, tree))
3090 goto jumpTable; /* no need for the comparison */
3092 /* for the cases defined do */
3096 operand *compare = geniCodeLogic (cond,
3097 operandFromValue (caseVals),
3100 sprintf (buffer, "_case_%d_%d",
3101 tree->values.switchVals.swNum,
3102 (int) floatFromVal (caseVals));
3103 trueLabel = newiTempLabel (buffer);
3105 ic = newiCodeCondition (compare, trueLabel, NULL);
3107 caseVals = caseVals->next;
3112 /* if default is present then goto break else break */
3113 if (tree->values.switchVals.swDefault)
3114 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3116 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3118 falseLabel = newiTempLabel (buffer);
3119 geniCodeGoto (falseLabel);
3122 ast2iCode (tree->right,lvl+1);
3125 /*-----------------------------------------------------------------*/
3126 /* geniCodeInline - intermediate code for inline assembler */
3127 /*-----------------------------------------------------------------*/
3129 geniCodeInline (ast * tree)
3133 ic = newiCode (INLINEASM, NULL, NULL);
3134 IC_INLINE (ic) = tree->values.inlineasm;
3138 /*-----------------------------------------------------------------*/
3139 /* geniCodeArrayInit - intermediate code for array initializer */
3140 /*-----------------------------------------------------------------*/
3142 geniCodeArrayInit (ast * tree, operand *array)
3146 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3147 ic = newiCode (ARRAYINIT, array, NULL);
3148 IC_ARRAYILIST (ic) = tree->values.constlist;
3150 operand *left=newOperand(), *right=newOperand();
3151 left->type=right->type=SYMBOL;
3152 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3153 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3154 ic = newiCode (ARRAYINIT, left, right);
3159 /*-----------------------------------------------------------------*/
3160 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3161 /* particular case. Ie : assigning or dereferencing array or ptr */
3162 /*-----------------------------------------------------------------*/
3163 set * lvaluereqSet = NULL;
3164 typedef struct lvalItem
3171 /*-----------------------------------------------------------------*/
3172 /* addLvaluereq - add a flag for lvalreq for current ast level */
3173 /*-----------------------------------------------------------------*/
3174 void addLvaluereq(int lvl)
3176 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3179 addSetHead(&lvaluereqSet,lpItem);
3182 /*-----------------------------------------------------------------*/
3183 /* delLvaluereq - del a flag for lvalreq for current ast level */
3184 /*-----------------------------------------------------------------*/
3188 lpItem = getSet(&lvaluereqSet);
3189 if(lpItem) Safe_free(lpItem);
3191 /*-----------------------------------------------------------------*/
3192 /* clearLvaluereq - clear lvalreq flag */
3193 /*-----------------------------------------------------------------*/
3194 void clearLvaluereq()
3197 lpItem = peekSet(lvaluereqSet);
3198 if(lpItem) lpItem->req = 0;
3200 /*-----------------------------------------------------------------*/
3201 /* getLvaluereq - get the last lvalreq level */
3202 /*-----------------------------------------------------------------*/
3203 int getLvaluereqLvl()
3206 lpItem = peekSet(lvaluereqSet);
3207 if(lpItem) return lpItem->lvl;
3210 /*-----------------------------------------------------------------*/
3211 /* isLvaluereq - is lvalreq valid for this level ? */
3212 /*-----------------------------------------------------------------*/
3213 int isLvaluereq(int lvl)
3216 lpItem = peekSet(lvaluereqSet);
3217 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3221 /*-----------------------------------------------------------------*/
3222 /* ast2iCode - creates an icodeList from an ast */
3223 /*-----------------------------------------------------------------*/
3225 ast2iCode (ast * tree,int lvl)
3227 operand *left = NULL;
3228 operand *right = NULL;
3231 /* set the global variables for filename & line number */
3233 filename = tree->filename;
3235 lineno = tree->lineno;
3237 block = tree->block;
3239 scopeLevel = tree->level;
3241 if (tree->type == EX_VALUE)
3242 return operandFromValue (tree->opval.val);
3244 if (tree->type == EX_LINK)
3245 return operandFromLink (tree->opval.lnk);
3247 /* if we find a nullop */
3248 if (tree->type == EX_OP &&
3249 (tree->opval.op == NULLOP ||
3250 tree->opval.op == BLOCK))
3252 ast2iCode (tree->left,lvl+1);
3253 ast2iCode (tree->right,lvl+1);
3257 /* special cases for not evaluating */
3258 if (tree->opval.op != ':' &&
3259 tree->opval.op != '?' &&
3260 tree->opval.op != CALL &&
3261 tree->opval.op != IFX &&
3262 tree->opval.op != LABEL &&
3263 tree->opval.op != GOTO &&
3264 tree->opval.op != SWITCH &&
3265 tree->opval.op != FUNCTION &&
3266 tree->opval.op != INLINEASM)
3269 if (IS_ASSIGN_OP (tree->opval.op) ||
3270 IS_DEREF_OP (tree) ||
3271 (tree->opval.op == '&' && !tree->right) ||
3272 tree->opval.op == PTR_OP)
3275 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3276 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3279 left = operandFromAst (tree->left,lvl);
3281 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3282 left = geniCodeRValue (left, TRUE);
3286 left = operandFromAst (tree->left,lvl);
3288 if (tree->opval.op == INC_OP ||
3289 tree->opval.op == DEC_OP)
3292 right = operandFromAst (tree->right,lvl);
3297 right = operandFromAst (tree->right,lvl);
3301 /* now depending on the type of operand */
3302 /* this will be a biggy */
3303 switch (tree->opval.op)
3306 case '[': /* array operation */
3308 //sym_link *ltype = operandType (left);
3309 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3310 left = geniCodeRValue (left, FALSE);
3311 right = geniCodeRValue (right, TRUE);
3314 return geniCodeArray (left, right,lvl);
3316 case '.': /* structure dereference */
3317 if (IS_PTR (operandType (left)))
3318 left = geniCodeRValue (left, TRUE);
3320 left = geniCodeRValue (left, FALSE);
3322 return geniCodeStruct (left, right, tree->lvalue);
3324 case PTR_OP: /* structure pointer dereference */
3327 pType = operandType (left);
3328 left = geniCodeRValue (left, TRUE);
3330 setOClass (pType, getSpec (operandType (left)));
3333 return geniCodeStruct (left, right, tree->lvalue);
3335 case INC_OP: /* increment operator */
3337 return geniCodePostInc (left);
3339 return geniCodePreInc (right);
3341 case DEC_OP: /* decrement operator */
3343 return geniCodePostDec (left);
3345 return geniCodePreDec (right);
3347 case '&': /* bitwise and or address of operator */
3349 { /* this is a bitwise operator */
3350 left = geniCodeRValue (left, FALSE);
3351 right = geniCodeRValue (right, FALSE);
3352 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3355 return geniCodeAddressOf (left);
3357 case '|': /* bitwise or & xor */
3359 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3360 geniCodeRValue (right, FALSE),
3365 return geniCodeDivision (geniCodeRValue (left, FALSE),
3366 geniCodeRValue (right, FALSE));
3369 return geniCodeModulus (geniCodeRValue (left, FALSE),
3370 geniCodeRValue (right, FALSE));
3373 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3374 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3376 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3380 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3381 geniCodeRValue (right, FALSE));
3383 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3387 return geniCodeAdd (geniCodeRValue (left, FALSE),
3388 geniCodeRValue (right, FALSE),lvl);
3390 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3393 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3394 geniCodeRValue (right, FALSE));
3397 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3398 geniCodeRValue (right, FALSE));
3400 return geniCodeCast (operandType (left),
3401 geniCodeRValue (right, FALSE), FALSE);
3407 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3411 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3412 setOperandType (op, UCHARTYPE);
3423 return geniCodeLogic (geniCodeRValue (left, FALSE),
3424 geniCodeRValue (right, FALSE),
3427 return geniCodeConditional (tree,lvl);
3430 return operandFromLit (getSize (tree->right->ftype));
3434 sym_link *rtype = operandType (right);
3435 sym_link *ltype = operandType (left);
3436 if (IS_PTR (rtype) && IS_ITEMP (right)
3437 && right->isaddr && compareType (rtype->next, ltype) == 1)
3438 right = geniCodeRValue (right, TRUE);
3440 right = geniCodeRValue (right, FALSE);
3442 geniCodeAssign (left, right, 0);
3447 geniCodeAssign (left,
3448 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3450 geniCodeRValue (right, FALSE),FALSE), 0);
3454 geniCodeAssign (left,
3455 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3457 geniCodeRValue (right, FALSE)), 0);
3460 geniCodeAssign (left,
3461 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3463 geniCodeRValue (right, FALSE)), 0);
3466 sym_link *rtype = operandType (right);
3467 sym_link *ltype = operandType (left);
3468 if (IS_PTR (rtype) && IS_ITEMP (right)
3469 && right->isaddr && compareType (rtype->next, ltype) == 1)
3470 right = geniCodeRValue (right, TRUE);
3472 right = geniCodeRValue (right, FALSE);
3475 return geniCodeAssign (left,
3476 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3482 sym_link *rtype = operandType (right);
3483 sym_link *ltype = operandType (left);
3484 if (IS_PTR (rtype) && IS_ITEMP (right)
3485 && right->isaddr && compareType (rtype->next, ltype) == 1)
3487 right = geniCodeRValue (right, TRUE);
3491 right = geniCodeRValue (right, FALSE);
3494 geniCodeAssign (left,
3495 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3501 geniCodeAssign (left,
3502 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3504 geniCodeRValue (right, FALSE)), 0);
3507 geniCodeAssign (left,
3508 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3510 geniCodeRValue (right, FALSE)), 0);
3513 geniCodeAssign (left,
3514 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3516 geniCodeRValue (right, FALSE),
3518 operandType (left)), 0);
3521 geniCodeAssign (left,
3522 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3524 geniCodeRValue (right, FALSE),
3526 operandType (left)), 0);
3529 geniCodeAssign (left,
3530 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3532 geniCodeRValue (right, FALSE),
3534 operandType (left)), 0);
3536 return geniCodeRValue (right, FALSE);
3539 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3542 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3543 return ast2iCode (tree->right,lvl+1);
3546 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3547 return ast2iCode (tree->right,lvl+1);
3550 geniCodeFunctionBody (tree,lvl);
3554 geniCodeReturn (right);
3558 geniCodeIfx (tree,lvl);
3562 geniCodeSwitch (tree,lvl);
3566 geniCodeInline (tree);
3570 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3577 /*-----------------------------------------------------------------*/
3578 /* reverseICChain - gets from the list and creates a linkedlist */
3579 /*-----------------------------------------------------------------*/
3586 while ((loop = getSet (&iCodeChain)))
3598 /*-----------------------------------------------------------------*/
3599 /* iCodeFromAst - given an ast will convert it to iCode */
3600 /*-----------------------------------------------------------------*/
3602 iCodeFromAst (ast * tree)
3604 returnLabel = newiTempLabel ("_return");
3605 entryLabel = newiTempLabel ("_entry");
3607 return reverseiCChain ();