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));
686 IC_ARGS (nic) = IC_ARGS (ic);
690 IC_INLINE (nic) = IC_INLINE (ic);
694 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
698 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
699 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
700 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
706 /*-----------------------------------------------------------------*/
707 /* getTableEntry - gets the table entry for the given operator */
708 /*-----------------------------------------------------------------*/
710 getTableEntry (int oper)
714 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
715 if (oper == codeTable[i].icode)
716 return &codeTable[i];
721 /*-----------------------------------------------------------------*/
722 /* newiTempOperand - new intermediate temp operand */
723 /*-----------------------------------------------------------------*/
725 newiTempOperand (sym_link * type, char throwType)
728 operand *op = newOperand ();
732 itmp = newiTemp (NULL);
734 etype = getSpec (type);
736 if (IS_LITERAL (etype))
739 /* copy the type information */
741 itmp->etype = getSpec (itmp->type = (throwType ? type :
742 copyLinkChain (type)));
743 if (IS_LITERAL (itmp->etype))
745 SPEC_SCLS (itmp->etype) = S_REGISTER;
746 SPEC_OCLS (itmp->etype) = reg;
749 op->operand.symOperand = itmp;
750 op->key = itmp->key = ++operandKey;
754 /*-----------------------------------------------------------------*/
755 /* operandType - returns the type chain for an operand */
756 /*-----------------------------------------------------------------*/
758 operandType (operand * op)
760 /* depending on type of operand */
765 return op->operand.valOperand->type;
768 return op->operand.symOperand->type;
771 return op->operand.typeOperand;
773 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
774 " operand type not known ");
775 assert (0); /* should never come here */
776 /* Just to keep the compiler happy */
777 return (sym_link *) 0;
781 /*-----------------------------------------------------------------*/
782 /* isParamterToCall - will return 1 if op is a parameter to args */
783 /*-----------------------------------------------------------------*/
785 isParameterToCall (value * args, operand * op)
792 isSymbolEqual (op->operand.symOperand, tval->sym))
799 /*-----------------------------------------------------------------*/
800 /* isOperandGlobal - return 1 if operand is a global variable */
801 /*-----------------------------------------------------------------*/
803 isOperandGlobal (operand * op)
811 if (op->type == SYMBOL &&
812 (op->operand.symOperand->level == 0 ||
813 IS_STATIC (op->operand.symOperand->etype) ||
814 IS_EXTERN (op->operand.symOperand->etype))
821 /*-----------------------------------------------------------------*/
822 /* isOperandVolatile - return 1 if the operand is volatile */
823 /*-----------------------------------------------------------------*/
825 isOperandVolatile (operand * op, bool chkTemp)
830 if (IS_ITEMP (op) && !chkTemp)
833 opetype = getSpec (optype = operandType (op));
835 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
838 if (IS_VOLATILE (opetype))
843 /*-----------------------------------------------------------------*/
844 /* isOperandLiteral - returns 1 if an operand contains a literal */
845 /*-----------------------------------------------------------------*/
847 isOperandLiteral (operand * op)
854 opetype = getSpec (operandType (op));
856 if (IS_LITERAL (opetype))
861 /*-----------------------------------------------------------------*/
862 /* isOperandInFarSpace - will return true if operand is in farSpace */
863 /*-----------------------------------------------------------------*/
865 isOperandInFarSpace (operand * op)
875 if (!IS_TRUE_SYMOP (op))
878 etype = SPIL_LOC (op)->etype;
884 etype = getSpec (operandType (op));
886 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
889 /*-----------------------------------------------------------------*/
890 /* isOperandOnStack - will return true if operand is on stack */
891 /*-----------------------------------------------------------------*/
893 isOperandOnStack (operand * op)
903 etype = getSpec (operandType (op));
905 return ((IN_STACK (etype)) ? TRUE : FALSE);
908 /*-----------------------------------------------------------------*/
909 /* operandLitValue - literal value of an operand */
910 /*-----------------------------------------------------------------*/
912 operandLitValue (operand * op)
914 assert (isOperandLiteral (op));
916 return floatFromVal (op->operand.valOperand);
919 /*-----------------------------------------------------------------*/
920 /* operandOperation - perforoms operations on operands */
921 /*-----------------------------------------------------------------*/
923 operandOperation (operand * left, operand * right,
924 int op, sym_link * type)
926 sym_link *let , *ret=NULL;
927 operand *retval = (operand *) 0;
929 assert (isOperandLiteral (left));
930 let = getSpec(operandType(left));
932 assert (isOperandLiteral (right));
933 ret = getSpec(operandType(left));
939 retval = operandFromValue (valCastLiteral (type,
940 operandLitValue (left) +
941 operandLitValue (right)));
944 retval = operandFromValue (valCastLiteral (type,
945 operandLitValue (left) -
946 operandLitValue (right)));
949 retval = operandFromValue (valCastLiteral (type,
950 operandLitValue (left) *
951 operandLitValue (right)));
954 if ((unsigned long) operandLitValue (right) == 0)
956 werror (E_DIVIDE_BY_ZERO);
961 retval = operandFromValue (valCastLiteral (type,
962 operandLitValue (left) /
963 operandLitValue (right)));
966 if ((unsigned long) operandLitValue (right) == 0) {
967 werror (E_DIVIDE_BY_ZERO);
971 retval = operandFromLit ((SPEC_USIGN(let) ?
972 (unsigned long) operandLitValue (left) :
973 (long) operandLitValue (left)) %
975 (unsigned long) operandLitValue (right) :
976 (long) operandLitValue (right)));
980 retval = operandFromLit ((SPEC_USIGN(let) ?
981 (unsigned long) operandLitValue (left) :
982 (long) operandLitValue (left)) <<
984 (unsigned long) operandLitValue (right) :
985 (long) operandLitValue (right)));
988 retval = operandFromLit ((SPEC_USIGN(let) ?
989 (unsigned long) operandLitValue (left) :
990 (long) operandLitValue (left)) >>
992 (unsigned long) operandLitValue (right) :
993 (long) 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 (operandLitValue (left) !=
1009 operandLitValue (right));
1012 retval = operandFromLit (operandLitValue (left) >
1013 operandLitValue (right));
1016 retval = operandFromLit (operandLitValue (left) >=
1017 operandLitValue (right));
1020 retval = operandFromLit ((long)operandLitValue(left) &
1021 (long)operandLitValue(right));
1024 retval = operandFromLit ((long)operandLitValue (left) |
1025 (long)operandLitValue (right));
1028 retval = operandFromLit ((long)operandLitValue (left) ^
1029 (long)operandLitValue (right));
1032 retval = operandFromLit (operandLitValue (left) &&
1033 operandLitValue (right));
1036 retval = operandFromLit (operandLitValue (left) ||
1037 operandLitValue (right));
1041 long i = (long) operandLitValue (left);
1043 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1049 long i = (long) operandLitValue (left);
1051 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1057 retval = operandFromLit (-1 * operandLitValue (left));
1061 retval = operandFromLit (~((long) operandLitValue (left)));
1065 retval = operandFromLit (!operandLitValue (left));
1069 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1070 " operandOperation invalid operator ");
1078 /*-----------------------------------------------------------------*/
1079 /* isOperandEqual - compares two operand & return 1 if they r = */
1080 /*-----------------------------------------------------------------*/
1082 isOperandEqual (operand * left, operand * right)
1084 /* if the pointers are equal then they are equal */
1088 /* if either of them null then false */
1089 if (!left || !right)
1092 if (left->type != right->type)
1095 if (IS_SYMOP (left) && IS_SYMOP (right))
1096 return left->key == right->key;
1098 /* if types are the same */
1102 return isSymbolEqual (left->operand.symOperand,
1103 right->operand.symOperand);
1105 return (floatFromVal (left->operand.valOperand) ==
1106 floatFromVal (right->operand.valOperand));
1108 if (compareType (left->operand.typeOperand,
1109 right->operand.typeOperand) == 1)
1116 /*-------------------------------------------------------------------*/
1117 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1118 /*-------------------------------------------------------------------*/
1120 isiCodeEqual (iCode * left, iCode * right)
1122 /* if the same pointer */
1126 /* if either of them null */
1127 if (!left || !right)
1130 /* if operand are the same */
1131 if (left->op == right->op)
1134 /* compare all the elements depending on type */
1135 if (left->op != IFX)
1137 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1139 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1145 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1147 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1149 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1158 /*-----------------------------------------------------------------*/
1159 /* newiTempFromOp - create a temp Operand with same attributes */
1160 /*-----------------------------------------------------------------*/
1162 newiTempFromOp (operand * op)
1172 nop = newiTempOperand (operandType (op), TRUE);
1173 nop->isaddr = op->isaddr;
1174 nop->isvolatile = op->isvolatile;
1175 nop->isGlobal = op->isGlobal;
1176 nop->isLiteral = op->isLiteral;
1177 nop->usesDefs = op->usesDefs;
1178 nop->isParm = op->isParm;
1182 /*-----------------------------------------------------------------*/
1183 /* operand from operand - creates an operand holder for the type */
1184 /*-----------------------------------------------------------------*/
1186 operandFromOperand (operand * op)
1192 nop = newOperand ();
1193 nop->type = op->type;
1194 nop->isaddr = op->isaddr;
1196 nop->isvolatile = op->isvolatile;
1197 nop->isGlobal = op->isGlobal;
1198 nop->isLiteral = op->isLiteral;
1199 nop->usesDefs = op->usesDefs;
1200 nop->isParm = op->isParm;
1205 nop->operand.symOperand = op->operand.symOperand;
1208 nop->operand.valOperand = op->operand.valOperand;
1211 nop->operand.typeOperand = op->operand.typeOperand;
1218 /*-----------------------------------------------------------------*/
1219 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1220 /*-----------------------------------------------------------------*/
1222 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1224 operand *nop = operandFromOperand (op);
1226 if (nop->type == SYMBOL)
1228 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1229 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1235 /*-----------------------------------------------------------------*/
1236 /* operandFromSymbol - creates an operand from a symbol */
1237 /*-----------------------------------------------------------------*/
1239 operandFromSymbol (symbol * sym)
1244 /* if the symbol's type is a literal */
1245 /* then it is an enumerator type */
1246 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1247 return operandFromValue (valFromType (sym->etype));
1250 sym->key = ++operandKey;
1252 /* if this an implicit variable, means struct/union */
1253 /* member so just return it */
1254 if (sym->implicit || IS_FUNC (sym->type))
1258 op->operand.symOperand = sym;
1260 op->isvolatile = isOperandVolatile (op, TRUE);
1261 op->isGlobal = isOperandGlobal (op);
1265 /* under the following conditions create a
1266 register equivalent for a local symbol */
1267 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1268 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1269 (!(options.model == MODEL_FLAT24)) ) &&
1270 options.stackAuto == 0)
1273 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1274 !IS_FUNC (sym->type) && /* not a function */
1275 !sym->_isparm && /* not a parameter */
1276 sym->level && /* is a local variable */
1277 !sym->addrtaken && /* whose address has not been taken */
1278 !sym->reqv && /* does not already have a reg equivalence */
1279 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1280 !IS_STATIC (sym->etype) && /* and not declared static */
1281 !sym->islbl && /* not a label */
1282 ok && /* farspace check */
1283 !IS_BITVAR (sym->etype) /* not a bit variable */
1287 /* we will use it after all optimizations
1288 and before liveRange calculation */
1289 sym->reqv = newiTempOperand (sym->type, 0);
1290 sym->reqv->key = sym->key;
1291 OP_SYMBOL (sym->reqv)->key = sym->key;
1292 OP_SYMBOL (sym->reqv)->isreqv = 1;
1293 OP_SYMBOL (sym->reqv)->islocal = 1;
1294 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1295 SPIL_LOC (sym->reqv) = sym;
1298 if (!IS_AGGREGATE (sym->type))
1302 op->operand.symOperand = sym;
1305 op->isvolatile = isOperandVolatile (op, TRUE);
1306 op->isGlobal = isOperandGlobal (op);
1307 op->isPtr = IS_PTR (operandType (op));
1308 op->isParm = sym->_isparm;
1313 /* itemp = &[_symbol] */
1315 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1316 IC_LEFT (ic)->type = SYMBOL;
1317 IC_LEFT (ic)->operand.symOperand = sym;
1318 IC_LEFT (ic)->key = sym->key;
1319 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1320 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1321 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1324 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1325 if (IS_ARRAY (sym->type))
1327 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1328 IC_RESULT (ic)->isaddr = 0;
1331 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1335 return IC_RESULT (ic);
1338 /*-----------------------------------------------------------------*/
1339 /* operandFromValue - creates an operand from value */
1340 /*-----------------------------------------------------------------*/
1342 operandFromValue (value * val)
1346 /* if this is a symbol then do the symbol thing */
1348 return operandFromSymbol (val->sym);
1350 /* this is not a symbol */
1353 op->operand.valOperand = val;
1354 op->isLiteral = isOperandLiteral (op);
1358 /*-----------------------------------------------------------------*/
1359 /* operandFromLink - operand from typeChain */
1360 /*-----------------------------------------------------------------*/
1362 operandFromLink (sym_link * type)
1366 /* operand from sym_link */
1372 op->operand.typeOperand = copyLinkChain (type);
1376 /*-----------------------------------------------------------------*/
1377 /* operandFromLit - makes an operand from a literal value */
1378 /*-----------------------------------------------------------------*/
1380 operandFromLit (double i)
1382 return operandFromValue (valueFromLit (i));
1385 /*-----------------------------------------------------------------*/
1386 /* operandFromAst - creates an operand from an ast */
1387 /*-----------------------------------------------------------------*/
1389 operandFromAst (ast * tree,int lvl)
1395 /* depending on type do */
1399 return ast2iCode (tree,lvl+1);
1403 return operandFromValue (tree->opval.val);
1407 return operandFromLink (tree->opval.lnk);
1411 /* Just to keep the comiler happy */
1412 return (operand *) 0;
1415 /*-----------------------------------------------------------------*/
1416 /* setOperandType - sets the operand's type to the given type */
1417 /*-----------------------------------------------------------------*/
1419 setOperandType (operand * op, sym_link * type)
1421 /* depending on the type of operand */
1426 op->operand.valOperand->etype =
1427 getSpec (op->operand.valOperand->type =
1428 copyLinkChain (type));
1432 if (op->operand.symOperand->isitmp)
1433 op->operand.symOperand->etype =
1434 getSpec (op->operand.symOperand->type =
1435 copyLinkChain (type));
1437 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1438 "attempt to modify type of source");
1442 op->operand.typeOperand = copyLinkChain (type);
1447 /*-----------------------------------------------------------------*/
1448 /* Get size in byte of ptr need to access an array */
1449 /*-----------------------------------------------------------------*/
1451 getArraySizePtr (operand * op)
1453 sym_link *ltype = operandType(op);
1457 int size = getSize(ltype);
1458 return(IS_GENPTR(ltype)?(size-1):size);
1463 sym_link *letype = getSpec(ltype);
1464 switch (PTR_TYPE (SPEC_OCLS (letype)))
1476 return (GPTRSIZE-1);
1485 /*-----------------------------------------------------------------*/
1486 /* perform "usual unary conversions" */
1487 /*-----------------------------------------------------------------*/
1489 usualUnaryConversions (operand * op)
1491 if (IS_INTEGRAL (operandType (op)))
1493 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1496 return geniCodeCast (INTTYPE, op, TRUE);
1502 /*-----------------------------------------------------------------*/
1503 /* perform "usual binary conversions" */
1504 /*-----------------------------------------------------------------*/
1506 usualBinaryConversions (operand ** op1, operand ** op2)
1509 sym_link *rtype = operandType (*op2);
1510 sym_link *ltype = operandType (*op1);
1512 ctype = computeType (ltype, rtype);
1513 *op1 = geniCodeCast (ctype, *op1, TRUE);
1514 *op2 = geniCodeCast (ctype, *op2, TRUE);
1519 /*-----------------------------------------------------------------*/
1520 /* geniCodeValueAtAddress - generate intermeditate code for value */
1522 /*-----------------------------------------------------------------*/
1524 geniCodeRValue (operand * op, bool force)
1527 sym_link *type = operandType (op);
1528 sym_link *etype = getSpec (type);
1530 /* if this is an array & already */
1531 /* an address then return this */
1532 if (IS_AGGREGATE (type) ||
1533 (IS_PTR (type) && !force && !op->isaddr))
1534 return operandFromOperand (op);
1536 /* if this is not an address then must be */
1537 /* rvalue already so return this one */
1541 /* if this is not a temp symbol then */
1542 if (!IS_ITEMP (op) &&
1544 !IN_FARSPACE (SPEC_OCLS (etype)))
1546 op = operandFromOperand (op);
1551 if (IS_SPEC (type) &&
1552 IS_TRUE_SYMOP (op) &&
1553 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1554 /* TARGET_IS_DS390)) */
1555 (options.model == MODEL_FLAT24) ))
1557 op = operandFromOperand (op);
1562 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1563 if (IS_PTR (type) && op->isaddr && force)
1566 type = copyLinkChain (type);
1568 IC_RESULT (ic) = newiTempOperand (type, 1);
1569 IC_RESULT (ic)->isaddr = 0;
1571 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1575 return IC_RESULT (ic);
1578 /*-----------------------------------------------------------------*/
1579 /* geniCodeCast - changes the value from one type to another */
1580 /*-----------------------------------------------------------------*/
1582 geniCodeCast (sym_link * type, operand * op, bool implicit)
1586 sym_link *opetype = getSpec (optype = operandType (op));
1590 /* one of them has size zero then error */
1591 if (IS_VOID (optype))
1593 werror (E_CAST_ZERO);
1597 /* if the operand is already the desired type then do nothing */
1598 if (compareType (type, optype) == 1)
1601 /* if this is a literal then just change the type & return */
1602 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1603 return operandFromValue (valCastLiteral (type,
1604 operandLitValue (op)));
1606 /* if casting to/from pointers, do some checking */
1607 if (IS_PTR(type)) { // to a pointer
1608 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1609 if (IS_INTEGRAL(optype)) {
1610 // maybe this is NULL, than it's ok.
1611 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1612 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1613 // no way to set the storage
1614 if (IS_LITERAL(optype)) {
1615 werror(E_LITERAL_GENERIC);
1618 werror(E_NONPTR2_GENPTR);
1621 } else if (implicit) {
1622 werror(W_INTEGRAL2PTR_NOCAST);
1627 // shouldn't do that with float, array or structure unless to void
1628 if (!IS_VOID(getSpec(type)) &&
1629 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1630 werror(E_INCOMPAT_TYPES);
1634 } else { // from a pointer to a pointer
1635 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1636 // if not a pointer to a function
1637 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1638 if (implicit) { // if not to generic, they have to match
1639 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1640 werror(E_INCOMPAT_PTYPES);
1647 } else { // to a non pointer
1648 if (IS_PTR(optype)) { // from a pointer
1649 if (implicit) { // sneaky
1650 if (IS_INTEGRAL(type)) {
1651 werror(W_PTR2INTEGRAL_NOCAST);
1653 } else { // shouldn't do that with float, array or structure
1654 werror(E_INCOMPAT_TYPES);
1661 /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
1662 implicit?"(implicit)":"", errors); */
1663 fprintf (stderr, "from type '");
1664 printTypeChain (optype, stderr);
1665 fprintf (stderr, "' to type '");
1666 printTypeChain (type, stderr);
1667 fprintf (stderr, "'\n");
1670 /* if they are the same size create an assignment */
1671 if (getSize (type) == getSize (optype) &&
1672 !IS_BITFIELD (type) &&
1674 !IS_FLOAT (optype) &&
1675 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1676 (!IS_SPEC (type) && !IS_SPEC (optype))))
1679 ic = newiCode ('=', NULL, op);
1680 IC_RESULT (ic) = newiTempOperand (type, 0);
1681 SPIL_LOC (IC_RESULT (ic)) =
1682 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1683 IC_RESULT (ic)->isaddr = 0;
1687 ic = newiCode (CAST, operandFromLink (type),
1688 geniCodeRValue (op, FALSE));
1690 IC_RESULT (ic) = newiTempOperand (type, 0);
1693 /* preserve the storage class & output class */
1694 /* of the original variable */
1695 restype = getSpec (operandType (IC_RESULT (ic)));
1696 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1697 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1700 return IC_RESULT (ic);
1703 /*-----------------------------------------------------------------*/
1704 /* geniCodeLabel - will create a Label */
1705 /*-----------------------------------------------------------------*/
1707 geniCodeLabel (symbol * label)
1711 ic = newiCodeLabelGoto (LABEL, label);
1715 /*-----------------------------------------------------------------*/
1716 /* geniCodeGoto - will create a Goto */
1717 /*-----------------------------------------------------------------*/
1719 geniCodeGoto (symbol * label)
1723 ic = newiCodeLabelGoto (GOTO, label);
1727 /*-----------------------------------------------------------------*/
1728 /* geniCodeMultiply - gen intermediate code for multiplication */
1729 /*-----------------------------------------------------------------*/
1731 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1738 /* if they are both literal then we know the result */
1739 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1740 return operandFromValue (valMult (left->operand.valOperand,
1741 right->operand.valOperand));
1743 if (IS_LITERAL(retype)) {
1744 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1747 resType = usualBinaryConversions (&left, &right);
1749 rtype = operandType (right);
1750 retype = getSpec (rtype);
1751 ltype = operandType (left);
1752 letype = getSpec (ltype);
1756 SPEC_NOUN(getSpec(resType))=V_INT;
1759 /* if the right is a literal & power of 2 */
1760 /* then make it a left shift */
1761 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1762 efficient in most cases than 2 bytes result = 2 bytes << literal
1763 if port has 1 byte muldiv */
1764 if (p2 && !IS_FLOAT (letype) &&
1765 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1766 (port->support.muldiv == 1)))
1768 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1770 /* LEFT_OP need same size for left and result, */
1771 left = geniCodeCast (resType, left, TRUE);
1772 ltype = operandType (left);
1774 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1778 ic = newiCode ('*', left, right); /* normal multiplication */
1779 /* if the size left or right > 1 then support routine */
1780 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1784 IC_RESULT (ic) = newiTempOperand (resType, 1);
1787 return IC_RESULT (ic);
1790 /*-----------------------------------------------------------------*/
1791 /* geniCodeDivision - gen intermediate code for division */
1792 /*-----------------------------------------------------------------*/
1794 geniCodeDivision (operand * left, operand * right)
1799 sym_link *rtype = operandType (right);
1800 sym_link *retype = getSpec (rtype);
1801 sym_link *ltype = operandType (left);
1802 sym_link *letype = getSpec (ltype);
1804 resType = usualBinaryConversions (&left, &right);
1806 /* if the right is a literal & power of 2 */
1807 /* then make it a right shift */
1808 if (IS_LITERAL (retype) &&
1809 !IS_FLOAT (letype) &&
1810 (p2 = powof2 ((unsigned long)
1811 floatFromVal (right->operand.valOperand)))) {
1812 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1816 ic = newiCode ('/', left, right); /* normal division */
1817 /* if the size left or right > 1 then support routine */
1818 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1821 IC_RESULT (ic) = newiTempOperand (resType, 0);
1824 return IC_RESULT (ic);
1826 /*-----------------------------------------------------------------*/
1827 /* geniCodeModulus - gen intermediate code for modulus */
1828 /*-----------------------------------------------------------------*/
1830 geniCodeModulus (operand * left, operand * right)
1836 /* if they are both literal then we know the result */
1837 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1838 return operandFromValue (valMod (left->operand.valOperand,
1839 right->operand.valOperand));
1841 resType = usualBinaryConversions (&left, &right);
1843 /* now they are the same size */
1844 ic = newiCode ('%', left, right);
1846 /* if the size left or right > 1 then support routine */
1847 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1849 IC_RESULT (ic) = newiTempOperand (resType, 0);
1852 return IC_RESULT (ic);
1855 /*-----------------------------------------------------------------*/
1856 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1857 /*-----------------------------------------------------------------*/
1859 geniCodePtrPtrSubtract (operand * left, operand * right)
1865 /* if they are both literals then */
1866 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1868 result = operandFromValue (valMinus (left->operand.valOperand,
1869 right->operand.valOperand));
1873 ic = newiCode ('-', left, right);
1875 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1879 return geniCodeDivision (result,
1880 operandFromLit (getSize (ltype->next)));
1883 /*-----------------------------------------------------------------*/
1884 /* geniCodeSubtract - generates code for subtraction */
1885 /*-----------------------------------------------------------------*/
1887 geniCodeSubtract (operand * left, operand * right)
1894 /* if they both pointers then */
1895 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1896 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1897 return geniCodePtrPtrSubtract (left, right);
1899 /* if they are both literal then we know the result */
1900 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1901 && left->isLiteral && right->isLiteral)
1902 return operandFromValue (valMinus (left->operand.valOperand,
1903 right->operand.valOperand));
1905 /* if left is an array or pointer */
1906 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1908 isarray = left->isaddr;
1909 right = geniCodeMultiply (right,
1910 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1911 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1914 { /* make them the same size */
1915 resType = usualBinaryConversions (&left, &right);
1918 ic = newiCode ('-', left, right);
1920 IC_RESULT (ic) = newiTempOperand (resType, 1);
1921 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1923 /* if left or right is a float */
1924 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1928 return IC_RESULT (ic);
1931 /*-----------------------------------------------------------------*/
1932 /* geniCodeAdd - generates iCode for addition */
1933 /*-----------------------------------------------------------------*/
1935 geniCodeAdd (operand * left, operand * right,int lvl)
1943 /* if left is an array then array access */
1944 if (IS_ARRAY (ltype))
1945 return geniCodeArray (left, right,lvl);
1947 /* if the right side is LITERAL zero */
1948 /* return the left side */
1949 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1952 /* if left is literal zero return right */
1953 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1956 /* if left is an array or pointer then size */
1959 isarray = left->isaddr;
1960 // there is no need to multiply with 1
1961 if (getSize(ltype->next)!=1) {
1962 size = operandFromLit (getSize (ltype->next));
1963 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1965 resType = copyLinkChain (ltype);
1968 { /* make them the same size */
1969 resType = usualBinaryConversions (&left, &right);
1972 /* if they are both literals then we know */
1973 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1974 && left->isLiteral && right->isLiteral)
1975 return operandFromValue (valPlus (valFromType (letype),
1976 valFromType (retype)));
1978 ic = newiCode ('+', left, right);
1980 IC_RESULT (ic) = newiTempOperand (resType, 1);
1981 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1983 /* if left or right is a float then support
1985 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1990 return IC_RESULT (ic);
1994 /*-----------------------------------------------------------------*/
1995 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
1996 /*-----------------------------------------------------------------*/
1998 aggrToPtr (sym_link * type, bool force)
2004 if (IS_PTR (type) && !force)
2007 etype = getSpec (type);
2011 /* if the output class is generic */
2012 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2013 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2015 /* if the variable was declared a constant */
2016 /* then the pointer points to a constant */
2017 if (IS_CONSTANT (etype))
2018 DCL_PTR_CONST (ptype) = 1;
2020 /* the variable was volatile then pointer to volatile */
2021 if (IS_VOLATILE (etype))
2022 DCL_PTR_VOLATILE (ptype) = 1;
2026 /*-----------------------------------------------------------------*/
2027 /* geniCodeArray2Ptr - array to pointer */
2028 /*-----------------------------------------------------------------*/
2030 geniCodeArray2Ptr (operand * op)
2032 sym_link *optype = operandType (op);
2033 sym_link *opetype = getSpec (optype);
2035 /* set the pointer depending on the storage class */
2036 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2037 DCL_PTR_CONST (optype) = port->mem.code_ro;
2040 /* if the variable was declared a constant */
2041 /* then the pointer points to a constant */
2042 if (IS_CONSTANT (opetype))
2043 DCL_PTR_CONST (optype) = 1;
2045 /* the variable was volatile then pointer to volatile */
2046 if (IS_VOLATILE (opetype))
2047 DCL_PTR_VOLATILE (optype) = 1;
2053 /*-----------------------------------------------------------------*/
2054 /* geniCodeArray - array access */
2055 /*-----------------------------------------------------------------*/
2057 geniCodeArray (operand * left, operand * right,int lvl)
2060 sym_link *ltype = operandType (left);
2064 if (IS_PTR (ltype->next) && left->isaddr)
2066 left = geniCodeRValue (left, FALSE);
2068 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2071 right = geniCodeMultiply (right,
2072 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2074 /* we can check for limits here */
2075 if (isOperandLiteral (right) &&
2078 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2080 werror (E_ARRAY_BOUND);
2081 right = operandFromLit (0);
2084 ic = newiCode ('+', left, right);
2086 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2087 !IS_AGGREGATE (ltype->next) &&
2088 !IS_PTR (ltype->next))
2089 ? ltype : ltype->next), 0);
2091 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2093 return IC_RESULT (ic);
2096 /*-----------------------------------------------------------------*/
2097 /* geniCodeStruct - generates intermediate code for structres */
2098 /*-----------------------------------------------------------------*/
2100 geniCodeStruct (operand * left, operand * right, bool islval)
2103 sym_link *type = operandType (left);
2104 sym_link *etype = getSpec (type);
2106 symbol *element = getStructElement (SPEC_STRUCT (etype),
2107 right->operand.symOperand);
2109 /* add the offset */
2110 ic = newiCode ('+', left, operandFromLit (element->offset));
2112 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2114 /* preserve the storage & output class of the struct */
2115 /* as well as the volatile attribute */
2116 retype = getSpec (operandType (IC_RESULT (ic)));
2117 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2118 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2119 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2121 if (IS_PTR (element->type))
2122 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2124 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2128 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2131 /*-----------------------------------------------------------------*/
2132 /* geniCodePostInc - generate int code for Post increment */
2133 /*-----------------------------------------------------------------*/
2135 geniCodePostInc (operand * op)
2139 sym_link *optype = operandType (op);
2141 operand *rv = (IS_ITEMP (op) ?
2142 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2144 sym_link *rvtype = operandType (rv);
2147 /* if this is not an address we have trouble */
2150 werror (E_LVALUE_REQUIRED, "++");
2154 rOp = newiTempOperand (rvtype, 0);
2155 OP_SYMBOL(rOp)->noSpilLoc = 1;
2158 OP_SYMBOL(rv)->noSpilLoc = 1;
2160 geniCodeAssign (rOp, rv, 0);
2162 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2163 if (IS_FLOAT (rvtype))
2164 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2166 ic = newiCode ('+', rv, operandFromLit (size));
2168 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2171 geniCodeAssign (op, result, 0);
2177 /*-----------------------------------------------------------------*/
2178 /* geniCodePreInc - generate code for preIncrement */
2179 /*-----------------------------------------------------------------*/
2181 geniCodePreInc (operand * op)
2184 sym_link *optype = operandType (op);
2185 operand *rop = (IS_ITEMP (op) ?
2186 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2188 sym_link *roptype = operandType (rop);
2194 werror (E_LVALUE_REQUIRED, "++");
2199 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2200 if (IS_FLOAT (roptype))
2201 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2203 ic = newiCode ('+', rop, operandFromLit (size));
2204 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2208 return geniCodeAssign (op, result, 0);
2211 /*-----------------------------------------------------------------*/
2212 /* geniCodePostDec - generates code for Post decrement */
2213 /*-----------------------------------------------------------------*/
2215 geniCodePostDec (operand * op)
2219 sym_link *optype = operandType (op);
2221 operand *rv = (IS_ITEMP (op) ?
2222 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2224 sym_link *rvtype = operandType (rv);
2227 /* if this is not an address we have trouble */
2230 werror (E_LVALUE_REQUIRED, "--");
2234 rOp = newiTempOperand (rvtype, 0);
2235 OP_SYMBOL(rOp)->noSpilLoc = 1;
2238 OP_SYMBOL(rv)->noSpilLoc = 1;
2240 geniCodeAssign (rOp, rv, 0);
2242 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2243 if (IS_FLOAT (rvtype))
2244 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2246 ic = newiCode ('-', rv, operandFromLit (size));
2248 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2251 geniCodeAssign (op, result, 0);
2257 /*-----------------------------------------------------------------*/
2258 /* geniCodePreDec - generate code for pre decrement */
2259 /*-----------------------------------------------------------------*/
2261 geniCodePreDec (operand * op)
2264 sym_link *optype = operandType (op);
2265 operand *rop = (IS_ITEMP (op) ?
2266 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2268 sym_link *roptype = operandType (rop);
2274 werror (E_LVALUE_REQUIRED, "--");
2279 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2280 if (IS_FLOAT (roptype))
2281 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2283 ic = newiCode ('-', rop, operandFromLit (size));
2284 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2288 return geniCodeAssign (op, result, 0);
2292 /*-----------------------------------------------------------------*/
2293 /* geniCodeBitwise - gen int code for bitWise operators */
2294 /*-----------------------------------------------------------------*/
2296 geniCodeBitwise (operand * left, operand * right,
2297 int oper, sym_link * resType)
2301 left = geniCodeCast (resType, left, TRUE);
2302 right = geniCodeCast (resType, right, TRUE);
2304 ic = newiCode (oper, left, right);
2305 IC_RESULT (ic) = newiTempOperand (resType, 0);
2308 return IC_RESULT (ic);
2311 /*-----------------------------------------------------------------*/
2312 /* geniCodeAddressOf - gens icode for '&' address of operator */
2313 /*-----------------------------------------------------------------*/
2315 geniCodeAddressOf (operand * op)
2319 sym_link *optype = operandType (op);
2320 sym_link *opetype = getSpec (optype);
2322 /* lvalue check already done in decorateType */
2323 /* this must be a lvalue */
2324 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2325 /* werror (E_LVALUE_REQUIRED,"&"); */
2330 p->class = DECLARATOR;
2332 /* set the pointer depending on the storage class */
2333 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2334 DCL_PTR_CONST (p) = port->mem.code_ro;
2336 /* make sure we preserve the const & volatile */
2337 if (IS_CONSTANT (opetype))
2338 DCL_PTR_CONST (p) = 1;
2340 if (IS_VOLATILE (opetype))
2341 DCL_PTR_VOLATILE (p) = 1;
2343 p->next = copyLinkChain (optype);
2345 /* if already a temp */
2348 setOperandType (op, p);
2353 /* other wise make this of the type coming in */
2354 ic = newiCode (ADDRESS_OF, op, NULL);
2355 IC_RESULT (ic) = newiTempOperand (p, 1);
2356 IC_RESULT (ic)->isaddr = 0;
2358 return IC_RESULT (ic);
2360 /*-----------------------------------------------------------------*/
2361 /* setOClass - sets the output class depending on the pointer type */
2362 /*-----------------------------------------------------------------*/
2364 setOClass (sym_link * ptr, sym_link * spec)
2366 switch (DCL_TYPE (ptr))
2369 SPEC_OCLS (spec) = data;
2373 SPEC_OCLS (spec) = generic;
2377 SPEC_OCLS (spec) = xdata;
2381 SPEC_OCLS (spec) = code;
2385 SPEC_OCLS (spec) = idata;
2389 SPEC_OCLS (spec) = xstack;
2393 SPEC_OCLS (spec) = eeprom;
2402 /*-----------------------------------------------------------------*/
2403 /* geniCodeDerefPtr - dereference pointer with '*' */
2404 /*-----------------------------------------------------------------*/
2406 geniCodeDerefPtr (operand * op,int lvl)
2408 sym_link *rtype, *retype;
2409 sym_link *optype = operandType (op);
2411 /* if this is a pointer then generate the rvalue */
2412 if (IS_PTR (optype))
2414 if (IS_TRUE_SYMOP (op))
2417 op = geniCodeRValue (op, TRUE);
2420 op = geniCodeRValue (op, TRUE);
2423 /* now get rid of the pointer part */
2424 if (isLvaluereq(lvl) && IS_ITEMP (op))
2426 retype = getSpec (rtype = copyLinkChain (optype));
2430 retype = getSpec (rtype = copyLinkChain (optype->next));
2433 /* if this is a pointer then outputclass needs 2b updated */
2434 if (IS_PTR (optype))
2435 setOClass (optype, retype);
2437 op->isGptr = IS_GENPTR (optype);
2439 /* if the pointer was declared as a constant */
2440 /* then we cannot allow assignment to the derefed */
2441 if (IS_PTR_CONST (optype))
2442 SPEC_CONST (retype) = 1;
2444 op->isaddr = (IS_PTR (rtype) ||
2445 IS_STRUCT (rtype) ||
2450 if (!isLvaluereq(lvl))
2451 op = geniCodeRValue (op, TRUE);
2453 setOperandType (op, rtype);
2458 /*-----------------------------------------------------------------*/
2459 /* geniCodeUnaryMinus - does a unary minus of the operand */
2460 /*-----------------------------------------------------------------*/
2462 geniCodeUnaryMinus (operand * op)
2465 sym_link *optype = operandType (op);
2467 if (IS_LITERAL (optype))
2468 return operandFromLit (-floatFromVal (op->operand.valOperand));
2470 ic = newiCode (UNARYMINUS, op, NULL);
2471 IC_RESULT (ic) = newiTempOperand (optype, 0);
2473 return IC_RESULT (ic);
2476 /*-----------------------------------------------------------------*/
2477 /* geniCodeLeftShift - gen i code for left shift */
2478 /*-----------------------------------------------------------------*/
2480 geniCodeLeftShift (operand * left, operand * right)
2484 ic = newiCode (LEFT_OP, left, right);
2485 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2487 return IC_RESULT (ic);
2490 /*-----------------------------------------------------------------*/
2491 /* geniCodeRightShift - gen i code for right shift */
2492 /*-----------------------------------------------------------------*/
2494 geniCodeRightShift (operand * left, operand * right)
2498 ic = newiCode (RIGHT_OP, left, right);
2499 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2501 return IC_RESULT (ic);
2504 /*-----------------------------------------------------------------*/
2505 /* geniCodeLogic- logic code */
2506 /*-----------------------------------------------------------------*/
2508 geniCodeLogic (operand * left, operand * right, int op)
2512 sym_link *rtype = operandType (right);
2513 sym_link *ltype = operandType (left);
2515 /* left is integral type and right is literal then
2516 check if the literal value is within bounds */
2517 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2519 checkConstantRange(ltype,
2520 OP_VALUE(right), "compare operation", 1);
2523 ctype = usualBinaryConversions (&left, &right);
2525 ic = newiCode (op, left, right);
2526 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2528 /* if comparing float
2529 and not a '==' || '!=' || '&&' || '||' (these
2531 if (IS_FLOAT(ctype) &&
2539 return IC_RESULT (ic);
2542 /*-----------------------------------------------------------------*/
2543 /* geniCodeUnary - for a a generic unary operation */
2544 /*-----------------------------------------------------------------*/
2546 geniCodeUnary (operand * op, int oper)
2548 iCode *ic = newiCode (oper, op, NULL);
2550 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2552 return IC_RESULT (ic);
2555 /*-----------------------------------------------------------------*/
2556 /* geniCodeConditional - geniCode for '?' ':' operation */
2557 /*-----------------------------------------------------------------*/
2559 geniCodeConditional (ast * tree,int lvl)
2562 symbol *falseLabel = newiTempLabel (NULL);
2563 symbol *exitLabel = newiTempLabel (NULL);
2564 operand *cond = ast2iCode (tree->left,lvl+1);
2565 operand *true, *false, *result;
2567 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2571 true = ast2iCode (tree->right->left,lvl+1);
2573 /* move the value to a new Operand */
2574 result = newiTempOperand (operandType (true), 0);
2575 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2577 /* generate an unconditional goto */
2578 geniCodeGoto (exitLabel);
2580 /* now for the right side */
2581 geniCodeLabel (falseLabel);
2583 false = ast2iCode (tree->right->right,lvl+1);
2584 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2586 /* create the exit label */
2587 geniCodeLabel (exitLabel);
2592 /*-----------------------------------------------------------------*/
2593 /* geniCodeAssign - generate code for assignment */
2594 /*-----------------------------------------------------------------*/
2596 geniCodeAssign (operand * left, operand * right, int nosupdate)
2599 sym_link *ltype = operandType (left);
2600 sym_link *rtype = operandType (right);
2602 if (!left->isaddr && !IS_ITEMP (left))
2604 werror (E_LVALUE_REQUIRED, "assignment");
2608 /* left is integral type and right is literal then
2609 check if the literal value is within bounds */
2610 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2612 checkConstantRange(ltype,
2613 OP_VALUE(right), "= operation", 0);
2616 /* if the left & right type don't exactly match */
2617 /* if pointer set then make sure the check is
2618 done with the type & not the pointer */
2619 /* then cast rights type to left */
2621 /* first check the type for pointer assignement */
2622 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2623 compareType (ltype, rtype) <= 0)
2625 if (compareType (ltype->next, rtype) < 0)
2626 right = geniCodeCast (ltype->next, right, TRUE);
2628 else if (compareType (ltype, rtype) < 0)
2629 right = geniCodeCast (ltype, right, TRUE);
2631 /* if left is a true symbol & ! volatile
2632 create an assignment to temporary for
2633 the right & then assign this temporary
2634 to the symbol this is SSA . isn't it simple
2635 and folks have published mountains of paper on it */
2636 if (IS_TRUE_SYMOP (left) &&
2637 !isOperandVolatile (left, FALSE) &&
2638 isOperandGlobal (left))
2642 if (IS_TRUE_SYMOP (right))
2643 sym = OP_SYMBOL (right);
2644 ic = newiCode ('=', NULL, right);
2645 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2646 SPIL_LOC (right) = sym;
2650 ic = newiCode ('=', NULL, right);
2651 IC_RESULT (ic) = left;
2654 /* if left isgptr flag is set then support
2655 routine will be required */
2659 ic->nosupdate = nosupdate;
2663 /*-----------------------------------------------------------------*/
2664 /* geniCodeSEParms - generate code for side effecting fcalls */
2665 /*-----------------------------------------------------------------*/
2667 geniCodeSEParms (ast * parms,int lvl)
2672 if (parms->type == EX_OP && parms->opval.op == PARAM)
2674 geniCodeSEParms (parms->left,lvl);
2675 geniCodeSEParms (parms->right,lvl);
2679 /* hack don't like this but too lazy to think of
2681 if (IS_ADDRESS_OF_OP (parms))
2682 parms->left->lvalue = 1;
2684 if (IS_CAST_OP (parms) &&
2685 IS_PTR (parms->ftype) &&
2686 IS_ADDRESS_OF_OP (parms->right))
2687 parms->right->left->lvalue = 1;
2689 parms->opval.oprnd =
2690 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2692 parms->type = EX_OPERAND;
2695 /*-----------------------------------------------------------------*/
2696 /* geniCodeParms - generates parameters */
2697 /*-----------------------------------------------------------------*/
2699 geniCodeParms (ast * parms, value *argVals, int *stack,
2700 sym_link * fetype, symbol * func,int lvl)
2708 if (argVals==NULL) {
2710 argVals=FUNC_ARGS(func->type);
2713 if (parms->argSym ||
2714 (parms->type!=EX_OP && parms->type!=EX_OPERAND)) {
2715 fprintf (stderr, "What the fuck??\n");
2718 /* if this is a param node then do the left & right */
2719 if (parms->type == EX_OP && parms->opval.op == PARAM)
2721 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2722 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2726 /* get the parameter value */
2727 if (parms->type == EX_OPERAND)
2728 pval = parms->opval.oprnd;
2731 /* maybe this else should go away ?? */
2732 /* hack don't like this but too lazy to think of
2734 if (IS_ADDRESS_OF_OP (parms))
2735 parms->left->lvalue = 1;
2737 if (IS_CAST_OP (parms) &&
2738 IS_PTR (parms->ftype) &&
2739 IS_ADDRESS_OF_OP (parms->right))
2740 parms->right->left->lvalue = 1;
2742 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2745 /* if register parm then make it a send */
2746 if ((parms->argSym && IS_REGPARM(parms->argSym->etype)) ||
2747 (IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)))
2749 ic = newiCode (SEND, pval, NULL);
2754 /* now decide whether to push or assign */
2755 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2759 operand *top = operandFromSymbol (argVals->sym);
2760 geniCodeAssign (top, pval, 1);
2764 sym_link *p = operandType (pval);
2766 ic = newiCode (IPUSH, pval, NULL);
2768 /* update the stack adjustment */
2769 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2774 argVals=argVals->next;
2778 /*-----------------------------------------------------------------*/
2779 /* geniCodeCall - generates temp code for calling */
2780 /*-----------------------------------------------------------------*/
2782 geniCodeCall (operand * left, ast * parms,int lvl)
2786 sym_link *type, *etype;
2789 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2790 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2791 werror (E_FUNCTION_EXPECTED);
2795 /* take care of parameters with side-effecting
2796 function calls in them, this is required to take care
2797 of overlaying function parameters */
2798 geniCodeSEParms (parms,lvl);
2800 /* first the parameters */
2801 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2803 /* now call : if symbol then pcall */
2804 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2805 ic = newiCode (PCALL, left, NULL);
2807 ic = newiCode (CALL, left, NULL);
2809 IC_ARGS (ic) = FUNC_ARGS(left->operand.symOperand->type);
2810 type = copyLinkChain (operandType (left)->next);
2811 etype = getSpec (type);
2812 SPEC_EXTR (etype) = 0;
2813 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2817 /* stack adjustment after call */
2818 ic->parmBytes = stack;
2823 /*-----------------------------------------------------------------*/
2824 /* geniCodeReceive - generate intermediate code for "receive" */
2825 /*-----------------------------------------------------------------*/
2827 geniCodeReceive (value * args)
2829 /* for all arguments that are passed in registers */
2833 if (IS_REGPARM (args->etype))
2835 operand *opr = operandFromValue (args);
2837 symbol *sym = OP_SYMBOL (opr);
2840 /* we will use it after all optimizations
2841 and before liveRange calculation */
2842 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2845 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2846 options.stackAuto == 0 &&
2847 /* !TARGET_IS_DS390) */
2848 (!(options.model == MODEL_FLAT24)) )
2853 opl = newiTempOperand (args->type, 0);
2855 sym->reqv->key = sym->key;
2856 OP_SYMBOL (sym->reqv)->key = sym->key;
2857 OP_SYMBOL (sym->reqv)->isreqv = 1;
2858 OP_SYMBOL (sym->reqv)->islocal = 0;
2859 SPIL_LOC (sym->reqv) = sym;
2863 ic = newiCode (RECEIVE, NULL, NULL);
2864 currFunc->recvSize = getSize (sym->etype);
2865 IC_RESULT (ic) = opr;
2873 /*-----------------------------------------------------------------*/
2874 /* geniCodeFunctionBody - create the function body */
2875 /*-----------------------------------------------------------------*/
2877 geniCodeFunctionBody (ast * tree,int lvl)
2884 /* reset the auto generation */
2890 func = ast2iCode (tree->left,lvl+1);
2891 fetype = getSpec (operandType (func));
2893 savelineno = lineno;
2894 lineno = OP_SYMBOL (func)->lineDef;
2895 /* create an entry label */
2896 geniCodeLabel (entryLabel);
2897 lineno = savelineno;
2899 /* create a proc icode */
2900 ic = newiCode (FUNCTION, func, NULL);
2901 /* if the function has parmas then */
2902 /* save the parameters information */
2903 ic->argLabel.args = tree->values.args;
2904 ic->lineno = OP_SYMBOL (func)->lineDef;
2908 /* for all parameters that are passed
2909 on registers add a "receive" */
2910 geniCodeReceive (tree->values.args);
2912 /* generate code for the body */
2913 ast2iCode (tree->right,lvl+1);
2915 /* create a label for return */
2916 geniCodeLabel (returnLabel);
2918 /* now generate the end proc */
2919 ic = newiCode (ENDFUNCTION, func, NULL);
2924 /*-----------------------------------------------------------------*/
2925 /* geniCodeReturn - gen icode for 'return' statement */
2926 /*-----------------------------------------------------------------*/
2928 geniCodeReturn (operand * op)
2932 /* if the operand is present force an rvalue */
2934 op = geniCodeRValue (op, FALSE);
2936 ic = newiCode (RETURN, op, NULL);
2940 /*-----------------------------------------------------------------*/
2941 /* geniCodeIfx - generates code for extended if statement */
2942 /*-----------------------------------------------------------------*/
2944 geniCodeIfx (ast * tree,int lvl)
2947 operand *condition = ast2iCode (tree->left,lvl+1);
2950 /* if condition is null then exit */
2954 condition = geniCodeRValue (condition, FALSE);
2956 cetype = getSpec (operandType (condition));
2957 /* if the condition is a literal */
2958 if (IS_LITERAL (cetype))
2960 if (floatFromVal (condition->operand.valOperand))
2962 if (tree->trueLabel)
2963 geniCodeGoto (tree->trueLabel);
2969 if (tree->falseLabel)
2970 geniCodeGoto (tree->falseLabel);
2977 if (tree->trueLabel)
2979 ic = newiCodeCondition (condition,
2984 if (tree->falseLabel)
2985 geniCodeGoto (tree->falseLabel);
2989 ic = newiCodeCondition (condition,
2996 ast2iCode (tree->right,lvl+1);
2999 /*-----------------------------------------------------------------*/
3000 /* geniCodeJumpTable - tries to create a jump table for switch */
3001 /*-----------------------------------------------------------------*/
3003 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3005 int min = 0, max = 0, t, cnt = 0;
3012 if (!tree || !caseVals)
3015 /* the criteria for creating a jump table is */
3016 /* all integer numbers between the maximum & minimum must */
3017 /* be present , the maximum value should not exceed 255 */
3018 min = max = (int) floatFromVal (vch = caseVals);
3019 sprintf (buffer, "_case_%d_%d",
3020 tree->values.switchVals.swNum,
3022 addSet (&labels, newiTempLabel (buffer));
3024 /* if there is only one case value then no need */
3025 if (!(vch = vch->next))
3030 if (((t = (int) floatFromVal (vch)) - max) != 1)
3032 sprintf (buffer, "_case_%d_%d",
3033 tree->values.switchVals.swNum,
3035 addSet (&labels, newiTempLabel (buffer));
3041 /* if the number of case statements <= 2 then */
3042 /* it is not economical to create the jump table */
3043 /* since two compares are needed for boundary conditions */
3044 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3047 if (tree->values.switchVals.swDefault)
3048 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3050 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3052 falseLabel = newiTempLabel (buffer);
3054 /* so we can create a jumptable */
3055 /* first we rule out the boundary conditions */
3056 /* if only optimization says so */
3057 if (!optimize.noJTabBoundary)
3059 sym_link *cetype = getSpec (operandType (cond));
3060 /* no need to check the lower bound if
3061 the condition is unsigned & minimum value is zero */
3062 if (!(min == 0 && SPEC_USIGN (cetype)))
3064 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3065 ic = newiCodeCondition (boundary, falseLabel, NULL);
3069 /* now for upper bounds */
3070 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3071 ic = newiCodeCondition (boundary, falseLabel, NULL);
3075 /* if the min is not zero then we no make it zero */
3078 cond = geniCodeSubtract (cond, operandFromLit (min));
3079 setOperandType (cond, UCHARTYPE);
3082 /* now create the jumptable */
3083 ic = newiCode (JUMPTABLE, NULL, NULL);
3084 IC_JTCOND (ic) = cond;
3085 IC_JTLABELS (ic) = labels;
3090 /*-----------------------------------------------------------------*/
3091 /* geniCodeSwitch - changes a switch to a if statement */
3092 /*-----------------------------------------------------------------*/
3094 geniCodeSwitch (ast * tree,int lvl)
3097 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3098 value *caseVals = tree->values.switchVals.swVals;
3099 symbol *trueLabel, *falseLabel;
3101 /* if we can make this a jump table */
3102 if (geniCodeJumpTable (cond, caseVals, tree))
3103 goto jumpTable; /* no need for the comparison */
3105 /* for the cases defined do */
3109 operand *compare = geniCodeLogic (cond,
3110 operandFromValue (caseVals),
3113 sprintf (buffer, "_case_%d_%d",
3114 tree->values.switchVals.swNum,
3115 (int) floatFromVal (caseVals));
3116 trueLabel = newiTempLabel (buffer);
3118 ic = newiCodeCondition (compare, trueLabel, NULL);
3120 caseVals = caseVals->next;
3125 /* if default is present then goto break else break */
3126 if (tree->values.switchVals.swDefault)
3127 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3129 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3131 falseLabel = newiTempLabel (buffer);
3132 geniCodeGoto (falseLabel);
3135 ast2iCode (tree->right,lvl+1);
3138 /*-----------------------------------------------------------------*/
3139 /* geniCodeInline - intermediate code for inline assembler */
3140 /*-----------------------------------------------------------------*/
3142 geniCodeInline (ast * tree)
3146 ic = newiCode (INLINEASM, NULL, NULL);
3147 IC_INLINE (ic) = tree->values.inlineasm;
3151 /*-----------------------------------------------------------------*/
3152 /* geniCodeArrayInit - intermediate code for array initializer */
3153 /*-----------------------------------------------------------------*/
3155 geniCodeArrayInit (ast * tree, operand *array)
3159 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3160 ic = newiCode (ARRAYINIT, array, NULL);
3161 IC_ARRAYILIST (ic) = tree->values.constlist;
3163 operand *left=newOperand(), *right=newOperand();
3164 left->type=right->type=SYMBOL;
3165 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3166 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3167 ic = newiCode (ARRAYINIT, left, right);
3172 /*-----------------------------------------------------------------*/
3173 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3174 /* particular case. Ie : assigning or dereferencing array or ptr */
3175 /*-----------------------------------------------------------------*/
3176 set * lvaluereqSet = NULL;
3177 typedef struct lvalItem
3184 /*-----------------------------------------------------------------*/
3185 /* addLvaluereq - add a flag for lvalreq for current ast level */
3186 /*-----------------------------------------------------------------*/
3187 void addLvaluereq(int lvl)
3189 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3192 addSetHead(&lvaluereqSet,lpItem);
3195 /*-----------------------------------------------------------------*/
3196 /* delLvaluereq - del a flag for lvalreq for current ast level */
3197 /*-----------------------------------------------------------------*/
3201 lpItem = getSet(&lvaluereqSet);
3202 if(lpItem) Safe_free(lpItem);
3204 /*-----------------------------------------------------------------*/
3205 /* clearLvaluereq - clear lvalreq flag */
3206 /*-----------------------------------------------------------------*/
3207 void clearLvaluereq()
3210 lpItem = peekSet(lvaluereqSet);
3211 if(lpItem) lpItem->req = 0;
3213 /*-----------------------------------------------------------------*/
3214 /* getLvaluereq - get the last lvalreq level */
3215 /*-----------------------------------------------------------------*/
3216 int getLvaluereqLvl()
3219 lpItem = peekSet(lvaluereqSet);
3220 if(lpItem) return lpItem->lvl;
3223 /*-----------------------------------------------------------------*/
3224 /* isLvaluereq - is lvalreq valid for this level ? */
3225 /*-----------------------------------------------------------------*/
3226 int isLvaluereq(int lvl)
3229 lpItem = peekSet(lvaluereqSet);
3230 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3234 /*-----------------------------------------------------------------*/
3235 /* ast2iCode - creates an icodeList from an ast */
3236 /*-----------------------------------------------------------------*/
3238 ast2iCode (ast * tree,int lvl)
3240 operand *left = NULL;
3241 operand *right = NULL;
3244 /* set the global variables for filename & line number */
3246 filename = tree->filename;
3248 lineno = tree->lineno;
3250 block = tree->block;
3252 scopeLevel = tree->level;
3254 if (tree->type == EX_VALUE)
3255 return operandFromValue (tree->opval.val);
3257 if (tree->type == EX_LINK)
3258 return operandFromLink (tree->opval.lnk);
3260 /* if we find a nullop */
3261 if (tree->type == EX_OP &&
3262 (tree->opval.op == NULLOP ||
3263 tree->opval.op == BLOCK))
3265 ast2iCode (tree->left,lvl+1);
3266 ast2iCode (tree->right,lvl+1);
3270 /* special cases for not evaluating */
3271 if (tree->opval.op != ':' &&
3272 tree->opval.op != '?' &&
3273 tree->opval.op != CALL &&
3274 tree->opval.op != IFX &&
3275 tree->opval.op != LABEL &&
3276 tree->opval.op != GOTO &&
3277 tree->opval.op != SWITCH &&
3278 tree->opval.op != FUNCTION &&
3279 tree->opval.op != INLINEASM)
3282 if (IS_ASSIGN_OP (tree->opval.op) ||
3283 IS_DEREF_OP (tree) ||
3284 (tree->opval.op == '&' && !tree->right) ||
3285 tree->opval.op == PTR_OP)
3288 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3289 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3292 left = operandFromAst (tree->left,lvl);
3294 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3295 left = geniCodeRValue (left, TRUE);
3299 left = operandFromAst (tree->left,lvl);
3301 if (tree->opval.op == INC_OP ||
3302 tree->opval.op == DEC_OP)
3305 right = operandFromAst (tree->right,lvl);
3310 right = operandFromAst (tree->right,lvl);
3314 /* now depending on the type of operand */
3315 /* this will be a biggy */
3316 switch (tree->opval.op)
3319 case '[': /* array operation */
3321 //sym_link *ltype = operandType (left);
3322 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3323 left = geniCodeRValue (left, FALSE);
3324 right = geniCodeRValue (right, TRUE);
3327 return geniCodeArray (left, right,lvl);
3329 case '.': /* structure dereference */
3330 if (IS_PTR (operandType (left)))
3331 left = geniCodeRValue (left, TRUE);
3333 left = geniCodeRValue (left, FALSE);
3335 return geniCodeStruct (left, right, tree->lvalue);
3337 case PTR_OP: /* structure pointer dereference */
3340 pType = operandType (left);
3341 left = geniCodeRValue (left, TRUE);
3343 setOClass (pType, getSpec (operandType (left)));
3346 return geniCodeStruct (left, right, tree->lvalue);
3348 case INC_OP: /* increment operator */
3350 return geniCodePostInc (left);
3352 return geniCodePreInc (right);
3354 case DEC_OP: /* decrement operator */
3356 return geniCodePostDec (left);
3358 return geniCodePreDec (right);
3360 case '&': /* bitwise and or address of operator */
3362 { /* this is a bitwise operator */
3363 left = geniCodeRValue (left, FALSE);
3364 right = geniCodeRValue (right, FALSE);
3365 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3368 return geniCodeAddressOf (left);
3370 case '|': /* bitwise or & xor */
3372 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3373 geniCodeRValue (right, FALSE),
3378 return geniCodeDivision (geniCodeRValue (left, FALSE),
3379 geniCodeRValue (right, FALSE));
3382 return geniCodeModulus (geniCodeRValue (left, FALSE),
3383 geniCodeRValue (right, FALSE));
3386 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3387 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3389 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3393 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3394 geniCodeRValue (right, FALSE));
3396 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3400 return geniCodeAdd (geniCodeRValue (left, FALSE),
3401 geniCodeRValue (right, FALSE),lvl);
3403 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3406 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3407 geniCodeRValue (right, FALSE));
3410 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3411 geniCodeRValue (right, FALSE));
3413 return geniCodeCast (operandType (left),
3414 geniCodeRValue (right, FALSE), FALSE);
3420 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3424 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3425 setOperandType (op, UCHARTYPE);
3436 return geniCodeLogic (geniCodeRValue (left, FALSE),
3437 geniCodeRValue (right, FALSE),
3440 return geniCodeConditional (tree,lvl);
3443 return operandFromLit (getSize (tree->right->ftype));
3447 sym_link *rtype = operandType (right);
3448 sym_link *ltype = operandType (left);
3449 if (IS_PTR (rtype) && IS_ITEMP (right)
3450 && right->isaddr && compareType (rtype->next, ltype) == 1)
3451 right = geniCodeRValue (right, TRUE);
3453 right = geniCodeRValue (right, FALSE);
3455 geniCodeAssign (left, right, 0);
3460 geniCodeAssign (left,
3461 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3463 geniCodeRValue (right, FALSE),FALSE), 0);
3467 geniCodeAssign (left,
3468 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3470 geniCodeRValue (right, FALSE)), 0);
3473 geniCodeAssign (left,
3474 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3476 geniCodeRValue (right, FALSE)), 0);
3479 sym_link *rtype = operandType (right);
3480 sym_link *ltype = operandType (left);
3481 if (IS_PTR (rtype) && IS_ITEMP (right)
3482 && right->isaddr && compareType (rtype->next, ltype) == 1)
3483 right = geniCodeRValue (right, TRUE);
3485 right = geniCodeRValue (right, FALSE);
3488 return geniCodeAssign (left,
3489 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3495 sym_link *rtype = operandType (right);
3496 sym_link *ltype = operandType (left);
3497 if (IS_PTR (rtype) && IS_ITEMP (right)
3498 && right->isaddr && compareType (rtype->next, ltype) == 1)
3500 right = geniCodeRValue (right, TRUE);
3504 right = geniCodeRValue (right, FALSE);
3507 geniCodeAssign (left,
3508 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3514 geniCodeAssign (left,
3515 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3517 geniCodeRValue (right, FALSE)), 0);
3520 geniCodeAssign (left,
3521 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3523 geniCodeRValue (right, FALSE)), 0);
3526 geniCodeAssign (left,
3527 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3529 geniCodeRValue (right, FALSE),
3531 operandType (left)), 0);
3534 geniCodeAssign (left,
3535 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3537 geniCodeRValue (right, FALSE),
3539 operandType (left)), 0);
3542 geniCodeAssign (left,
3543 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3545 geniCodeRValue (right, FALSE),
3547 operandType (left)), 0);
3549 return geniCodeRValue (right, FALSE);
3552 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3555 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3556 return ast2iCode (tree->right,lvl+1);
3559 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3560 return ast2iCode (tree->right,lvl+1);
3563 geniCodeFunctionBody (tree,lvl);
3567 geniCodeReturn (right);
3571 geniCodeIfx (tree,lvl);
3575 geniCodeSwitch (tree,lvl);
3579 geniCodeInline (tree);
3583 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3590 /*-----------------------------------------------------------------*/
3591 /* reverseICChain - gets from the list and creates a linkedlist */
3592 /*-----------------------------------------------------------------*/
3599 while ((loop = getSet (&iCodeChain)))
3611 /*-----------------------------------------------------------------*/
3612 /* iCodeFromAst - given an ast will convert it to iCode */
3613 /*-----------------------------------------------------------------*/
3615 iCodeFromAst (ast * tree)
3617 returnLabel = newiTempLabel ("_return");
3618 entryLabel = newiTempLabel ("_entry");
3620 return reverseiCChain ();