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 ru%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,
231 OP_SYMBOL(op)->ruonly
235 printTypeChain (operandType (op), file);
236 if (SPIL_LOC (op) && IS_ITEMP (op))
237 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
242 /* if assigned to registers */
243 if (OP_SYMBOL (op)->nRegs)
245 if (OP_SYMBOL (op)->isspilt)
247 if (!OP_SYMBOL (op)->remat)
248 if (OP_SYMBOL (op)->usl.spillLoc)
249 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
250 OP_SYMBOL (op)->usl.spillLoc->rname :
251 OP_SYMBOL (op)->usl.spillLoc->name));
253 fprintf (file, "[err]");
255 fprintf (file, "[remat]");
261 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
262 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
267 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
268 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
269 /* if assigned to registers */
270 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
276 OP_SYMBOL (op)->regs[i]->name :
285 printTypeChain (op->operand.typeOperand, file);
291 fprintf (file, "\n");
296 /*-----------------------------------------------------------------*/
297 /* print functions */
298 /*-----------------------------------------------------------------*/
299 PRINTFUNC (picGetValueAtAddr)
302 printOperand (IC_RESULT (ic), of);
305 printOperand (IC_LEFT (ic), of);
311 PRINTFUNC (picSetValueAtAddr)
315 printOperand (IC_LEFT (ic), of);
316 fprintf (of, "] = ");
317 printOperand (IC_RIGHT (ic), of);
321 PRINTFUNC (picAddrOf)
324 printOperand (IC_RESULT (ic), of);
325 if (IS_ITEMP (IC_LEFT (ic)))
328 fprintf (of, " = &[");
329 printOperand (IC_LEFT (ic), of);
332 if (IS_ITEMP (IC_LEFT (ic)))
333 fprintf (of, " offsetAdd ");
336 printOperand (IC_RIGHT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
344 PRINTFUNC (picJumpTable)
349 fprintf (of, "%s\t", s);
350 printOperand (IC_JTCOND (ic), of);
352 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
353 sym = setNextItem (IC_JTLABELS (ic)))
354 fprintf (of, "\t\t\t%s\n", sym->name);
357 PRINTFUNC (picGeneric)
360 printOperand (IC_RESULT (ic), of);
362 printOperand (IC_LEFT (ic), of);
363 fprintf (of, " %s ", s);
364 printOperand (IC_RIGHT (ic), of);
368 PRINTFUNC (picGenericOne)
373 printOperand (IC_RESULT (ic), of);
379 fprintf (of, "%s ", s);
380 printOperand (IC_LEFT (ic), of);
383 if (!IC_RESULT (ic) && !IC_LEFT (ic))
392 printOperand (IC_RESULT (ic), of);
394 printOperand (IC_LEFT (ic), of);
395 printOperand (IC_RIGHT (ic), of);
400 PRINTFUNC (picAssign)
404 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
407 printOperand (IC_RESULT (ic), of);
409 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
412 fprintf (of, " %s ", s);
413 printOperand (IC_RIGHT (ic), of);
420 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
426 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
433 printOperand (IC_COND (ic), of);
436 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
439 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
441 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
445 PRINTFUNC (picInline)
447 fprintf (of, "%s", IC_INLINE (ic));
450 PRINTFUNC (picReceive)
452 printOperand (IC_RESULT (ic), of);
453 fprintf (of, " = %s ", s);
454 printOperand (IC_LEFT (ic), of);
458 /*-----------------------------------------------------------------*/
459 /* piCode - prints one iCode */
460 /*-----------------------------------------------------------------*/
462 piCode (void *item, FILE * of)
470 icTab = getTableEntry (ic->op);
471 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
472 ic->filename, ic->lineno,
473 ic->seq, ic->key, ic->depth, ic->supportRtn);
474 icTab->iCodePrint (of, ic, icTab->printName);
480 printiCChain(ic,stdout);
482 /*-----------------------------------------------------------------*/
483 /* printiCChain - prints intermediate code for humans */
484 /*-----------------------------------------------------------------*/
486 printiCChain (iCode * icChain, FILE * of)
493 for (loop = icChain; loop; loop = loop->next)
495 if ((icTab = getTableEntry (loop->op)))
497 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
498 loop->filename, loop->lineno,
499 loop->seq, loop->key, loop->depth, loop->supportRtn);
501 icTab->iCodePrint (of, loop, icTab->printName);
507 /*-----------------------------------------------------------------*/
508 /* newOperand - allocate, init & return a new iCode */
509 /*-----------------------------------------------------------------*/
515 op = Safe_alloc ( sizeof (operand));
521 /*-----------------------------------------------------------------*/
522 /* newiCode - create and return a new iCode entry initialised */
523 /*-----------------------------------------------------------------*/
525 newiCode (int op, operand * left, operand * right)
529 ic = Safe_alloc ( sizeof (iCode));
532 ic->filename = filename;
534 ic->level = scopeLevel;
536 ic->key = iCodeKey++;
538 IC_RIGHT (ic) = right;
543 /*-----------------------------------------------------------------*/
544 /* newiCode for conditional statements */
545 /*-----------------------------------------------------------------*/
547 newiCodeCondition (operand * condition,
553 if (IS_VOID(operandType(condition))) {
554 werror(E_VOID_VALUE_USED);
557 ic = newiCode (IFX, NULL, NULL);
558 IC_COND (ic) = condition;
559 IC_TRUE (ic) = trueLabel;
560 IC_FALSE (ic) = falseLabel;
564 /*-----------------------------------------------------------------*/
565 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
566 /*-----------------------------------------------------------------*/
568 newiCodeLabelGoto (int op, symbol * label)
572 ic = newiCode (op, NULL, NULL);
574 ic->argLabel.label = label;
576 IC_RIGHT (ic) = NULL;
577 IC_RESULT (ic) = NULL;
581 /*-----------------------------------------------------------------*/
582 /* newiTemp - allocate & return a newItemp Variable */
583 /*-----------------------------------------------------------------*/
590 sprintf (buffer, "%s", s);
592 sprintf (buffer, "iTemp%d", iTempNum++);
593 itmp = newSymbol (buffer, 1);
594 strcpy (itmp->rname, itmp->name);
600 /*-----------------------------------------------------------------*/
601 /* newiTempLabel - creates a temp variable label */
602 /*-----------------------------------------------------------------*/
604 newiTempLabel (char *s)
608 /* check if this alredy exists */
609 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
613 itmplbl = newSymbol (s, 1);
616 sprintf (buffer, "iTempLbl%d", iTempLblNum++);
617 itmplbl = newSymbol (buffer, 1);
622 itmplbl->key = labelKey++;
623 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
627 /*-----------------------------------------------------------------*/
628 /* newiTempPreheaderLabel - creates a new preheader label */
629 /*-----------------------------------------------------------------*/
631 newiTempPreheaderLabel ()
635 sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
636 itmplbl = newSymbol (buffer, 1);
640 itmplbl->key = labelKey++;
641 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
646 /*-----------------------------------------------------------------*/
647 /* initiCode - initialises some iCode related stuff */
648 /*-----------------------------------------------------------------*/
655 /*-----------------------------------------------------------------*/
656 /* copyiCode - make a copy of the iCode given */
657 /*-----------------------------------------------------------------*/
659 copyiCode (iCode * ic)
661 iCode *nic = newiCode (ic->op, NULL, NULL);
663 nic->lineno = ic->lineno;
664 nic->filename = ic->filename;
665 nic->block = ic->block;
666 nic->level = ic->level;
667 nic->parmBytes = ic->parmBytes;
669 /* deal with the special cases first */
673 IC_COND (nic) = operandFromOperand (IC_COND (ic));
674 IC_TRUE (nic) = IC_TRUE (ic);
675 IC_FALSE (nic) = IC_FALSE (ic);
679 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
680 IC_JTLABELS (nic) = IC_JTLABELS (ic);
685 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
686 IC_LEFT (nic) = operandFromOperand (IC_LEFT (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 /* getBuiltInParms - returns parameters to a builtin functions */
921 /*-----------------------------------------------------------------*/
922 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
927 /* builtin functions uses only SEND for parameters */
928 while (ic->op != CALL) {
929 assert(ic->op == SEND && ic->builtinSEND);
930 ic->generated = 1; /* mark the icode as generated */
931 parms[*pcount] = IC_LEFT(ic);
937 /* make sure this is a builtin function call */
938 assert(IS_SYMOP(IC_LEFT(ic)));
939 ftype = operandType(IC_LEFT(ic));
940 assert(IFFUNC_ISBUILTIN(ftype));
944 /*-----------------------------------------------------------------*/
945 /* operandOperation - perforoms operations on operands */
946 /*-----------------------------------------------------------------*/
948 operandOperation (operand * left, operand * right,
949 int op, sym_link * type)
951 sym_link *let , *ret=NULL;
952 operand *retval = (operand *) 0;
954 assert (isOperandLiteral (left));
955 let = getSpec(operandType(left));
957 assert (isOperandLiteral (right));
958 ret = getSpec(operandType(left));
964 retval = operandFromValue (valCastLiteral (type,
965 operandLitValue (left) +
966 operandLitValue (right)));
969 retval = operandFromValue (valCastLiteral (type,
970 operandLitValue (left) -
971 operandLitValue (right)));
974 retval = operandFromValue (valCastLiteral (type,
975 operandLitValue (left) *
976 operandLitValue (right)));
979 if ((unsigned long) operandLitValue (right) == 0)
981 werror (E_DIVIDE_BY_ZERO);
986 retval = operandFromValue (valCastLiteral (type,
987 operandLitValue (left) /
988 operandLitValue (right)));
991 if ((unsigned long) operandLitValue (right) == 0) {
992 werror (E_DIVIDE_BY_ZERO);
996 retval = operandFromLit ((SPEC_USIGN(let) ?
997 (unsigned long) operandLitValue (left) :
998 (long) operandLitValue (left)) %
1000 (unsigned long) operandLitValue (right) :
1001 (long) operandLitValue (right)));
1005 retval = operandFromLit ((SPEC_USIGN(let) ?
1006 (unsigned long) operandLitValue (left) :
1007 (long) operandLitValue (left)) <<
1009 (unsigned long) operandLitValue (right) :
1010 (long) operandLitValue (right)));
1013 retval = operandFromLit ((SPEC_USIGN(let) ?
1014 (unsigned long) operandLitValue (left) :
1015 (long) operandLitValue (left)) >>
1017 (unsigned long) operandLitValue (right) :
1018 (long) operandLitValue (right)));
1021 retval = operandFromLit (operandLitValue (left) ==
1022 operandLitValue (right));
1025 retval = operandFromLit (operandLitValue (left) <
1026 operandLitValue (right));
1029 retval = operandFromLit (operandLitValue (left) <=
1030 operandLitValue (right));
1033 retval = operandFromLit (operandLitValue (left) !=
1034 operandLitValue (right));
1037 retval = operandFromLit (operandLitValue (left) >
1038 operandLitValue (right));
1041 retval = operandFromLit (operandLitValue (left) >=
1042 operandLitValue (right));
1045 retval = operandFromLit ((long)operandLitValue(left) &
1046 (long)operandLitValue(right));
1049 retval = operandFromLit ((long)operandLitValue (left) |
1050 (long)operandLitValue (right));
1053 retval = operandFromLit ((long)operandLitValue (left) ^
1054 (long)operandLitValue (right));
1057 retval = operandFromLit (operandLitValue (left) &&
1058 operandLitValue (right));
1061 retval = operandFromLit (operandLitValue (left) ||
1062 operandLitValue (right));
1066 long i = (long) operandLitValue (left);
1068 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1074 long i = (long) operandLitValue (left);
1076 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1082 retval = operandFromLit (-1 * operandLitValue (left));
1086 retval = operandFromLit (~((long) operandLitValue (left)));
1090 retval = operandFromLit (!operandLitValue (left));
1094 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1095 " operandOperation invalid operator ");
1103 /*-----------------------------------------------------------------*/
1104 /* isOperandEqual - compares two operand & return 1 if they r = */
1105 /*-----------------------------------------------------------------*/
1107 isOperandEqual (operand * left, operand * right)
1109 /* if the pointers are equal then they are equal */
1113 /* if either of them null then false */
1114 if (!left || !right)
1117 if (left->type != right->type)
1120 if (IS_SYMOP (left) && IS_SYMOP (right))
1121 return left->key == right->key;
1123 /* if types are the same */
1127 return isSymbolEqual (left->operand.symOperand,
1128 right->operand.symOperand);
1130 return (floatFromVal (left->operand.valOperand) ==
1131 floatFromVal (right->operand.valOperand));
1133 if (compareType (left->operand.typeOperand,
1134 right->operand.typeOperand) == 1)
1141 /*-------------------------------------------------------------------*/
1142 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1143 /*-------------------------------------------------------------------*/
1145 isiCodeEqual (iCode * left, iCode * right)
1147 /* if the same pointer */
1151 /* if either of them null */
1152 if (!left || !right)
1155 /* if operand are the same */
1156 if (left->op == right->op)
1159 /* compare all the elements depending on type */
1160 if (left->op != IFX)
1162 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1164 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1170 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1172 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1174 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1183 /*-----------------------------------------------------------------*/
1184 /* newiTempFromOp - create a temp Operand with same attributes */
1185 /*-----------------------------------------------------------------*/
1187 newiTempFromOp (operand * op)
1197 nop = newiTempOperand (operandType (op), TRUE);
1198 nop->isaddr = op->isaddr;
1199 nop->isvolatile = op->isvolatile;
1200 nop->isGlobal = op->isGlobal;
1201 nop->isLiteral = op->isLiteral;
1202 nop->usesDefs = op->usesDefs;
1203 nop->isParm = op->isParm;
1207 /*-----------------------------------------------------------------*/
1208 /* operand from operand - creates an operand holder for the type */
1209 /*-----------------------------------------------------------------*/
1211 operandFromOperand (operand * op)
1217 nop = newOperand ();
1218 nop->type = op->type;
1219 nop->isaddr = op->isaddr;
1221 nop->isvolatile = op->isvolatile;
1222 nop->isGlobal = op->isGlobal;
1223 nop->isLiteral = op->isLiteral;
1224 nop->usesDefs = op->usesDefs;
1225 nop->isParm = op->isParm;
1230 nop->operand.symOperand = op->operand.symOperand;
1233 nop->operand.valOperand = op->operand.valOperand;
1236 nop->operand.typeOperand = op->operand.typeOperand;
1243 /*-----------------------------------------------------------------*/
1244 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1245 /*-----------------------------------------------------------------*/
1247 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1249 operand *nop = operandFromOperand (op);
1251 if (nop->type == SYMBOL)
1253 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1254 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1260 /*-----------------------------------------------------------------*/
1261 /* operandFromSymbol - creates an operand from a symbol */
1262 /*-----------------------------------------------------------------*/
1264 operandFromSymbol (symbol * sym)
1269 /* if the symbol's type is a literal */
1270 /* then it is an enumerator type */
1271 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1272 return operandFromValue (valFromType (sym->etype));
1275 sym->key = ++operandKey;
1277 /* if this an implicit variable, means struct/union */
1278 /* member so just return it */
1279 if (sym->implicit || IS_FUNC (sym->type))
1283 op->operand.symOperand = sym;
1285 op->isvolatile = isOperandVolatile (op, TRUE);
1286 op->isGlobal = isOperandGlobal (op);
1290 /* under the following conditions create a
1291 register equivalent for a local symbol */
1292 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1293 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1294 (!(options.model == MODEL_FLAT24)) ) &&
1295 options.stackAuto == 0)
1298 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1299 !IS_FUNC (sym->type) && /* not a function */
1300 !sym->_isparm && /* not a parameter */
1301 sym->level && /* is a local variable */
1302 !sym->addrtaken && /* whose address has not been taken */
1303 !sym->reqv && /* does not already have a reg equivalence */
1304 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1305 !IS_STATIC (sym->etype) && /* and not declared static */
1306 !sym->islbl && /* not a label */
1307 ok && /* farspace check */
1308 !IS_BITVAR (sym->etype) /* not a bit variable */
1312 /* we will use it after all optimizations
1313 and before liveRange calculation */
1314 sym->reqv = newiTempOperand (sym->type, 0);
1315 sym->reqv->key = sym->key;
1316 OP_SYMBOL (sym->reqv)->key = sym->key;
1317 OP_SYMBOL (sym->reqv)->isreqv = 1;
1318 OP_SYMBOL (sym->reqv)->islocal = 1;
1319 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1320 SPIL_LOC (sym->reqv) = sym;
1323 if (!IS_AGGREGATE (sym->type))
1327 op->operand.symOperand = sym;
1330 op->isvolatile = isOperandVolatile (op, TRUE);
1331 op->isGlobal = isOperandGlobal (op);
1332 op->isPtr = IS_PTR (operandType (op));
1333 op->isParm = sym->_isparm;
1338 /* itemp = &[_symbol] */
1340 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1341 IC_LEFT (ic)->type = SYMBOL;
1342 IC_LEFT (ic)->operand.symOperand = sym;
1343 IC_LEFT (ic)->key = sym->key;
1344 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1345 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1346 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1349 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1350 if (IS_ARRAY (sym->type))
1352 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1353 IC_RESULT (ic)->isaddr = 0;
1356 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1360 return IC_RESULT (ic);
1363 /*-----------------------------------------------------------------*/
1364 /* operandFromValue - creates an operand from value */
1365 /*-----------------------------------------------------------------*/
1367 operandFromValue (value * val)
1371 /* if this is a symbol then do the symbol thing */
1373 return operandFromSymbol (val->sym);
1375 /* this is not a symbol */
1378 op->operand.valOperand = val;
1379 op->isLiteral = isOperandLiteral (op);
1383 /*-----------------------------------------------------------------*/
1384 /* operandFromLink - operand from typeChain */
1385 /*-----------------------------------------------------------------*/
1387 operandFromLink (sym_link * type)
1391 /* operand from sym_link */
1397 op->operand.typeOperand = copyLinkChain (type);
1401 /*-----------------------------------------------------------------*/
1402 /* operandFromLit - makes an operand from a literal value */
1403 /*-----------------------------------------------------------------*/
1405 operandFromLit (double i)
1407 return operandFromValue (valueFromLit (i));
1410 /*-----------------------------------------------------------------*/
1411 /* operandFromAst - creates an operand from an ast */
1412 /*-----------------------------------------------------------------*/
1414 operandFromAst (ast * tree,int lvl)
1420 /* depending on type do */
1424 return ast2iCode (tree,lvl+1);
1428 return operandFromValue (tree->opval.val);
1432 return operandFromLink (tree->opval.lnk);
1436 /* Just to keep the comiler happy */
1437 return (operand *) 0;
1440 /*-----------------------------------------------------------------*/
1441 /* setOperandType - sets the operand's type to the given type */
1442 /*-----------------------------------------------------------------*/
1444 setOperandType (operand * op, sym_link * type)
1446 /* depending on the type of operand */
1451 op->operand.valOperand->etype =
1452 getSpec (op->operand.valOperand->type =
1453 copyLinkChain (type));
1457 if (op->operand.symOperand->isitmp)
1458 op->operand.symOperand->etype =
1459 getSpec (op->operand.symOperand->type =
1460 copyLinkChain (type));
1462 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1463 "attempt to modify type of source");
1467 op->operand.typeOperand = copyLinkChain (type);
1472 /*-----------------------------------------------------------------*/
1473 /* Get size in byte of ptr need to access an array */
1474 /*-----------------------------------------------------------------*/
1476 getArraySizePtr (operand * op)
1478 sym_link *ltype = operandType(op);
1482 int size = getSize(ltype);
1483 return(IS_GENPTR(ltype)?(size-1):size);
1488 sym_link *letype = getSpec(ltype);
1489 switch (PTR_TYPE (SPEC_OCLS (letype)))
1501 return (GPTRSIZE-1);
1510 /*-----------------------------------------------------------------*/
1511 /* perform "usual unary conversions" */
1512 /*-----------------------------------------------------------------*/
1514 usualUnaryConversions (operand * op)
1516 if (IS_INTEGRAL (operandType (op)))
1518 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1521 return geniCodeCast (INTTYPE, op, TRUE);
1527 /*-----------------------------------------------------------------*/
1528 /* perform "usual binary conversions" */
1529 /*-----------------------------------------------------------------*/
1531 usualBinaryConversions (operand ** op1, operand ** op2)
1534 sym_link *rtype = operandType (*op2);
1535 sym_link *ltype = operandType (*op1);
1537 ctype = computeType (ltype, rtype);
1538 *op1 = geniCodeCast (ctype, *op1, TRUE);
1539 *op2 = geniCodeCast (ctype, *op2, TRUE);
1544 /*-----------------------------------------------------------------*/
1545 /* geniCodeValueAtAddress - generate intermeditate code for value */
1547 /*-----------------------------------------------------------------*/
1549 geniCodeRValue (operand * op, bool force)
1552 sym_link *type = operandType (op);
1553 sym_link *etype = getSpec (type);
1555 /* if this is an array & already */
1556 /* an address then return this */
1557 if (IS_AGGREGATE (type) ||
1558 (IS_PTR (type) && !force && !op->isaddr))
1559 return operandFromOperand (op);
1561 /* if this is not an address then must be */
1562 /* rvalue already so return this one */
1566 /* if this is not a temp symbol then */
1567 if (!IS_ITEMP (op) &&
1569 !IN_FARSPACE (SPEC_OCLS (etype)))
1571 op = operandFromOperand (op);
1576 if (IS_SPEC (type) &&
1577 IS_TRUE_SYMOP (op) &&
1578 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1579 /* TARGET_IS_DS390)) */
1580 (options.model == MODEL_FLAT24) ))
1582 op = operandFromOperand (op);
1587 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1588 if (IS_PTR (type) && op->isaddr && force)
1591 type = copyLinkChain (type);
1593 IC_RESULT (ic) = newiTempOperand (type, 1);
1594 IC_RESULT (ic)->isaddr = 0;
1596 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1600 return IC_RESULT (ic);
1603 /*-----------------------------------------------------------------*/
1604 /* geniCodeCast - changes the value from one type to another */
1605 /*-----------------------------------------------------------------*/
1607 geniCodeCast (sym_link * type, operand * op, bool implicit)
1611 sym_link *opetype = getSpec (optype = operandType (op));
1615 /* one of them has size zero then error */
1616 if (IS_VOID (optype))
1618 werror (E_CAST_ZERO);
1622 /* if the operand is already the desired type then do nothing */
1623 if (compareType (type, optype) == 1)
1626 /* if this is a literal then just change the type & return */
1627 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1628 return operandFromValue (valCastLiteral (type,
1629 operandLitValue (op)));
1631 /* if casting to/from pointers, do some checking */
1632 if (IS_PTR(type)) { // to a pointer
1633 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1634 if (IS_INTEGRAL(optype)) {
1635 // maybe this is NULL, than it's ok.
1636 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1637 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1638 // no way to set the storage
1639 if (IS_LITERAL(optype)) {
1640 werror(E_LITERAL_GENERIC);
1643 werror(E_NONPTR2_GENPTR);
1646 } else if (implicit) {
1647 werror(W_INTEGRAL2PTR_NOCAST);
1652 // shouldn't do that with float, array or structure unless to void
1653 if (!IS_VOID(getSpec(type)) &&
1654 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1655 werror(E_INCOMPAT_TYPES);
1659 } else { // from a pointer to a pointer
1660 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1661 // if not a pointer to a function
1662 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1663 if (implicit) { // if not to generic, they have to match
1664 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1665 werror(E_INCOMPAT_PTYPES);
1672 } else { // to a non pointer
1673 if (IS_PTR(optype)) { // from a pointer
1674 if (implicit) { // sneaky
1675 if (IS_INTEGRAL(type)) {
1676 werror(W_PTR2INTEGRAL_NOCAST);
1678 } else { // shouldn't do that with float, array or structure
1679 werror(E_INCOMPAT_TYPES);
1686 printFromToType (optype, type);
1689 /* if they are the same size create an assignment */
1690 if (getSize (type) == getSize (optype) &&
1691 !IS_BITFIELD (type) &&
1693 !IS_FLOAT (optype) &&
1694 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1695 (!IS_SPEC (type) && !IS_SPEC (optype))))
1698 ic = newiCode ('=', NULL, op);
1699 IC_RESULT (ic) = newiTempOperand (type, 0);
1700 SPIL_LOC (IC_RESULT (ic)) =
1701 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1702 IC_RESULT (ic)->isaddr = 0;
1706 ic = newiCode (CAST, operandFromLink (type),
1707 geniCodeRValue (op, FALSE));
1709 IC_RESULT (ic) = newiTempOperand (type, 0);
1712 /* preserve the storage class & output class */
1713 /* of the original variable */
1714 restype = getSpec (operandType (IC_RESULT (ic)));
1715 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1716 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1719 return IC_RESULT (ic);
1722 /*-----------------------------------------------------------------*/
1723 /* geniCodeLabel - will create a Label */
1724 /*-----------------------------------------------------------------*/
1726 geniCodeLabel (symbol * label)
1730 ic = newiCodeLabelGoto (LABEL, label);
1734 /*-----------------------------------------------------------------*/
1735 /* geniCodeGoto - will create a Goto */
1736 /*-----------------------------------------------------------------*/
1738 geniCodeGoto (symbol * label)
1742 ic = newiCodeLabelGoto (GOTO, label);
1746 /*-----------------------------------------------------------------*/
1747 /* geniCodeMultiply - gen intermediate code for multiplication */
1748 /*-----------------------------------------------------------------*/
1750 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1757 /* if they are both literal then we know the result */
1758 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1759 return operandFromValue (valMult (left->operand.valOperand,
1760 right->operand.valOperand));
1762 if (IS_LITERAL(retype)) {
1763 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1766 resType = usualBinaryConversions (&left, &right);
1768 rtype = operandType (right);
1769 retype = getSpec (rtype);
1770 ltype = operandType (left);
1771 letype = getSpec (ltype);
1775 SPEC_NOUN(getSpec(resType))=V_INT;
1778 /* if the right is a literal & power of 2 */
1779 /* then make it a left shift */
1780 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1781 efficient in most cases than 2 bytes result = 2 bytes << literal
1782 if port has 1 byte muldiv */
1783 if (p2 && !IS_FLOAT (letype) &&
1784 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1785 (port->support.muldiv == 1)))
1787 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1789 /* LEFT_OP need same size for left and result, */
1790 left = geniCodeCast (resType, left, TRUE);
1791 ltype = operandType (left);
1793 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1797 ic = newiCode ('*', left, right); /* normal multiplication */
1798 /* if the size left or right > 1 then support routine */
1799 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1803 IC_RESULT (ic) = newiTempOperand (resType, 1);
1806 return IC_RESULT (ic);
1809 /*-----------------------------------------------------------------*/
1810 /* geniCodeDivision - gen intermediate code for division */
1811 /*-----------------------------------------------------------------*/
1813 geniCodeDivision (operand * left, operand * right)
1818 sym_link *rtype = operandType (right);
1819 sym_link *retype = getSpec (rtype);
1820 sym_link *ltype = operandType (left);
1821 sym_link *letype = getSpec (ltype);
1823 resType = usualBinaryConversions (&left, &right);
1825 /* if the right is a literal & power of 2 */
1826 /* then make it a right shift */
1827 if (IS_LITERAL (retype) &&
1828 !IS_FLOAT (letype) &&
1829 (p2 = powof2 ((unsigned long)
1830 floatFromVal (right->operand.valOperand)))) {
1831 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
1835 ic = newiCode ('/', left, right); /* normal division */
1836 /* if the size left or right > 1 then support routine */
1837 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1840 IC_RESULT (ic) = newiTempOperand (resType, 0);
1843 return IC_RESULT (ic);
1845 /*-----------------------------------------------------------------*/
1846 /* geniCodeModulus - gen intermediate code for modulus */
1847 /*-----------------------------------------------------------------*/
1849 geniCodeModulus (operand * left, operand * right)
1855 /* if they are both literal then we know the result */
1856 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1857 return operandFromValue (valMod (left->operand.valOperand,
1858 right->operand.valOperand));
1860 resType = usualBinaryConversions (&left, &right);
1862 /* now they are the same size */
1863 ic = newiCode ('%', left, right);
1865 /* if the size left or right > 1 then support routine */
1866 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1868 IC_RESULT (ic) = newiTempOperand (resType, 0);
1871 return IC_RESULT (ic);
1874 /*-----------------------------------------------------------------*/
1875 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
1876 /*-----------------------------------------------------------------*/
1878 geniCodePtrPtrSubtract (operand * left, operand * right)
1884 /* if they are both literals then */
1885 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1887 result = operandFromValue (valMinus (left->operand.valOperand,
1888 right->operand.valOperand));
1892 ic = newiCode ('-', left, right);
1894 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
1898 return geniCodeDivision (result,
1899 operandFromLit (getSize (ltype->next)));
1902 /*-----------------------------------------------------------------*/
1903 /* geniCodeSubtract - generates code for subtraction */
1904 /*-----------------------------------------------------------------*/
1906 geniCodeSubtract (operand * left, operand * right)
1913 /* if they both pointers then */
1914 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
1915 (IS_PTR (rtype) || IS_ARRAY (rtype)))
1916 return geniCodePtrPtrSubtract (left, right);
1918 /* if they are both literal then we know the result */
1919 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1920 && left->isLiteral && right->isLiteral)
1921 return operandFromValue (valMinus (left->operand.valOperand,
1922 right->operand.valOperand));
1924 /* if left is an array or pointer */
1925 if (IS_PTR (ltype) || IS_ARRAY (ltype))
1927 isarray = left->isaddr;
1928 right = geniCodeMultiply (right,
1929 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
1930 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
1933 { /* make them the same size */
1934 resType = usualBinaryConversions (&left, &right);
1937 ic = newiCode ('-', left, right);
1939 IC_RESULT (ic) = newiTempOperand (resType, 1);
1940 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
1942 /* if left or right is a float */
1943 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
1947 return IC_RESULT (ic);
1950 /*-----------------------------------------------------------------*/
1951 /* geniCodeAdd - generates iCode for addition */
1952 /*-----------------------------------------------------------------*/
1954 geniCodeAdd (operand * left, operand * right,int lvl)
1962 /* if left is an array then array access */
1963 if (IS_ARRAY (ltype))
1964 return geniCodeArray (left, right,lvl);
1966 /* if the right side is LITERAL zero */
1967 /* return the left side */
1968 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
1971 /* if left is literal zero return right */
1972 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
1975 /* if left is an array or pointer then size */
1978 isarray = left->isaddr;
1979 // there is no need to multiply with 1
1980 if (getSize(ltype->next)!=1) {
1981 size = operandFromLit (getSize (ltype->next));
1982 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
1984 resType = copyLinkChain (ltype);
1987 { /* make them the same size */
1988 resType = usualBinaryConversions (&left, &right);
1991 /* if they are both literals then we know */
1992 if (IS_LITERAL (letype) && IS_LITERAL (retype)
1993 && left->isLiteral && right->isLiteral)
1994 return operandFromValue (valPlus (valFromType (letype),
1995 valFromType (retype)));
1997 ic = newiCode ('+', left, right);
1999 IC_RESULT (ic) = newiTempOperand (resType, 1);
2000 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2002 /* if left or right is a float then support
2004 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2009 return IC_RESULT (ic);
2013 /*-----------------------------------------------------------------*/
2014 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2015 /*-----------------------------------------------------------------*/
2017 aggrToPtr (sym_link * type, bool force)
2023 if (IS_PTR (type) && !force)
2026 etype = getSpec (type);
2030 /* if the output class is generic */
2031 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2032 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2034 /* if the variable was declared a constant */
2035 /* then the pointer points to a constant */
2036 if (IS_CONSTANT (etype))
2037 DCL_PTR_CONST (ptype) = 1;
2039 /* the variable was volatile then pointer to volatile */
2040 if (IS_VOLATILE (etype))
2041 DCL_PTR_VOLATILE (ptype) = 1;
2045 /*-----------------------------------------------------------------*/
2046 /* geniCodeArray2Ptr - array to pointer */
2047 /*-----------------------------------------------------------------*/
2049 geniCodeArray2Ptr (operand * op)
2051 sym_link *optype = operandType (op);
2052 sym_link *opetype = getSpec (optype);
2054 /* set the pointer depending on the storage class */
2055 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2056 DCL_PTR_CONST (optype) = port->mem.code_ro;
2059 /* if the variable was declared a constant */
2060 /* then the pointer points to a constant */
2061 if (IS_CONSTANT (opetype))
2062 DCL_PTR_CONST (optype) = 1;
2064 /* the variable was volatile then pointer to volatile */
2065 if (IS_VOLATILE (opetype))
2066 DCL_PTR_VOLATILE (optype) = 1;
2072 /*-----------------------------------------------------------------*/
2073 /* geniCodeArray - array access */
2074 /*-----------------------------------------------------------------*/
2076 geniCodeArray (operand * left, operand * right,int lvl)
2079 sym_link *ltype = operandType (left);
2083 if (IS_PTR (ltype->next) && left->isaddr)
2085 left = geniCodeRValue (left, FALSE);
2087 return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl);
2090 right = geniCodeMultiply (right,
2091 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2093 /* we can check for limits here */
2094 if (isOperandLiteral (right) &&
2097 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2099 werror (E_ARRAY_BOUND);
2100 right = operandFromLit (0);
2103 ic = newiCode ('+', left, right);
2105 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2106 !IS_AGGREGATE (ltype->next) &&
2107 !IS_PTR (ltype->next))
2108 ? ltype : ltype->next), 0);
2110 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2112 return IC_RESULT (ic);
2115 /*-----------------------------------------------------------------*/
2116 /* geniCodeStruct - generates intermediate code for structres */
2117 /*-----------------------------------------------------------------*/
2119 geniCodeStruct (operand * left, operand * right, bool islval)
2122 sym_link *type = operandType (left);
2123 sym_link *etype = getSpec (type);
2125 symbol *element = getStructElement (SPEC_STRUCT (etype),
2126 right->operand.symOperand);
2128 /* add the offset */
2129 ic = newiCode ('+', left, operandFromLit (element->offset));
2131 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2133 /* preserve the storage & output class of the struct */
2134 /* as well as the volatile attribute */
2135 retype = getSpec (operandType (IC_RESULT (ic)));
2136 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2137 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2138 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2140 if (IS_PTR (element->type))
2141 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2143 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2147 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2150 /*-----------------------------------------------------------------*/
2151 /* geniCodePostInc - generate int code for Post increment */
2152 /*-----------------------------------------------------------------*/
2154 geniCodePostInc (operand * op)
2158 sym_link *optype = operandType (op);
2160 operand *rv = (IS_ITEMP (op) ?
2161 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2163 sym_link *rvtype = operandType (rv);
2166 /* if this is not an address we have trouble */
2169 werror (E_LVALUE_REQUIRED, "++");
2173 rOp = newiTempOperand (rvtype, 0);
2174 OP_SYMBOL(rOp)->noSpilLoc = 1;
2177 OP_SYMBOL(rv)->noSpilLoc = 1;
2179 geniCodeAssign (rOp, rv, 0);
2181 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2182 if (IS_FLOAT (rvtype))
2183 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2185 ic = newiCode ('+', rv, operandFromLit (size));
2187 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2190 geniCodeAssign (op, result, 0);
2196 /*-----------------------------------------------------------------*/
2197 /* geniCodePreInc - generate code for preIncrement */
2198 /*-----------------------------------------------------------------*/
2200 geniCodePreInc (operand * op)
2203 sym_link *optype = operandType (op);
2204 operand *rop = (IS_ITEMP (op) ?
2205 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2207 sym_link *roptype = operandType (rop);
2213 werror (E_LVALUE_REQUIRED, "++");
2218 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2219 if (IS_FLOAT (roptype))
2220 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2222 ic = newiCode ('+', rop, operandFromLit (size));
2223 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2227 return geniCodeAssign (op, result, 0);
2230 /*-----------------------------------------------------------------*/
2231 /* geniCodePostDec - generates code for Post decrement */
2232 /*-----------------------------------------------------------------*/
2234 geniCodePostDec (operand * op)
2238 sym_link *optype = operandType (op);
2240 operand *rv = (IS_ITEMP (op) ?
2241 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2243 sym_link *rvtype = operandType (rv);
2246 /* if this is not an address we have trouble */
2249 werror (E_LVALUE_REQUIRED, "--");
2253 rOp = newiTempOperand (rvtype, 0);
2254 OP_SYMBOL(rOp)->noSpilLoc = 1;
2257 OP_SYMBOL(rv)->noSpilLoc = 1;
2259 geniCodeAssign (rOp, rv, 0);
2261 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2262 if (IS_FLOAT (rvtype))
2263 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2265 ic = newiCode ('-', rv, operandFromLit (size));
2267 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2270 geniCodeAssign (op, result, 0);
2276 /*-----------------------------------------------------------------*/
2277 /* geniCodePreDec - generate code for pre decrement */
2278 /*-----------------------------------------------------------------*/
2280 geniCodePreDec (operand * op)
2283 sym_link *optype = operandType (op);
2284 operand *rop = (IS_ITEMP (op) ?
2285 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2287 sym_link *roptype = operandType (rop);
2293 werror (E_LVALUE_REQUIRED, "--");
2298 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2299 if (IS_FLOAT (roptype))
2300 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2302 ic = newiCode ('-', rop, operandFromLit (size));
2303 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2307 return geniCodeAssign (op, result, 0);
2311 /*-----------------------------------------------------------------*/
2312 /* geniCodeBitwise - gen int code for bitWise operators */
2313 /*-----------------------------------------------------------------*/
2315 geniCodeBitwise (operand * left, operand * right,
2316 int oper, sym_link * resType)
2320 left = geniCodeCast (resType, left, TRUE);
2321 right = geniCodeCast (resType, right, TRUE);
2323 ic = newiCode (oper, left, right);
2324 IC_RESULT (ic) = newiTempOperand (resType, 0);
2327 return IC_RESULT (ic);
2330 /*-----------------------------------------------------------------*/
2331 /* geniCodeAddressOf - gens icode for '&' address of operator */
2332 /*-----------------------------------------------------------------*/
2334 geniCodeAddressOf (operand * op)
2338 sym_link *optype = operandType (op);
2339 sym_link *opetype = getSpec (optype);
2341 /* lvalue check already done in decorateType */
2342 /* this must be a lvalue */
2343 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2344 /* werror (E_LVALUE_REQUIRED,"&"); */
2349 p->class = DECLARATOR;
2351 /* set the pointer depending on the storage class */
2352 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2353 DCL_PTR_CONST (p) = port->mem.code_ro;
2355 /* make sure we preserve the const & volatile */
2356 if (IS_CONSTANT (opetype))
2357 DCL_PTR_CONST (p) = 1;
2359 if (IS_VOLATILE (opetype))
2360 DCL_PTR_VOLATILE (p) = 1;
2362 p->next = copyLinkChain (optype);
2364 /* if already a temp */
2367 setOperandType (op, p);
2372 /* other wise make this of the type coming in */
2373 ic = newiCode (ADDRESS_OF, op, NULL);
2374 IC_RESULT (ic) = newiTempOperand (p, 1);
2375 IC_RESULT (ic)->isaddr = 0;
2377 return IC_RESULT (ic);
2379 /*-----------------------------------------------------------------*/
2380 /* setOClass - sets the output class depending on the pointer type */
2381 /*-----------------------------------------------------------------*/
2383 setOClass (sym_link * ptr, sym_link * spec)
2385 switch (DCL_TYPE (ptr))
2388 SPEC_OCLS (spec) = data;
2392 SPEC_OCLS (spec) = generic;
2396 SPEC_OCLS (spec) = xdata;
2400 SPEC_OCLS (spec) = code;
2404 SPEC_OCLS (spec) = idata;
2408 SPEC_OCLS (spec) = xstack;
2412 SPEC_OCLS (spec) = eeprom;
2421 /*-----------------------------------------------------------------*/
2422 /* geniCodeDerefPtr - dereference pointer with '*' */
2423 /*-----------------------------------------------------------------*/
2425 geniCodeDerefPtr (operand * op,int lvl)
2427 sym_link *rtype, *retype;
2428 sym_link *optype = operandType (op);
2430 /* if this is a pointer then generate the rvalue */
2431 if (IS_PTR (optype))
2433 if (IS_TRUE_SYMOP (op))
2436 op = geniCodeRValue (op, TRUE);
2439 op = geniCodeRValue (op, TRUE);
2442 /* now get rid of the pointer part */
2443 if (isLvaluereq(lvl) && IS_ITEMP (op))
2445 retype = getSpec (rtype = copyLinkChain (optype));
2449 retype = getSpec (rtype = copyLinkChain (optype->next));
2452 /* if this is a pointer then outputclass needs 2b updated */
2453 if (IS_PTR (optype))
2454 setOClass (optype, retype);
2456 op->isGptr = IS_GENPTR (optype);
2458 /* if the pointer was declared as a constant */
2459 /* then we cannot allow assignment to the derefed */
2460 if (IS_PTR_CONST (optype))
2461 SPEC_CONST (retype) = 1;
2463 op->isaddr = (IS_PTR (rtype) ||
2464 IS_STRUCT (rtype) ||
2469 if (!isLvaluereq(lvl))
2470 op = geniCodeRValue (op, TRUE);
2472 setOperandType (op, rtype);
2477 /*-----------------------------------------------------------------*/
2478 /* geniCodeUnaryMinus - does a unary minus of the operand */
2479 /*-----------------------------------------------------------------*/
2481 geniCodeUnaryMinus (operand * op)
2484 sym_link *optype = operandType (op);
2486 if (IS_LITERAL (optype))
2487 return operandFromLit (-floatFromVal (op->operand.valOperand));
2489 ic = newiCode (UNARYMINUS, op, NULL);
2490 IC_RESULT (ic) = newiTempOperand (optype, 0);
2492 return IC_RESULT (ic);
2495 /*-----------------------------------------------------------------*/
2496 /* geniCodeLeftShift - gen i code for left shift */
2497 /*-----------------------------------------------------------------*/
2499 geniCodeLeftShift (operand * left, operand * right)
2503 ic = newiCode (LEFT_OP, left, right);
2504 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2506 return IC_RESULT (ic);
2509 /*-----------------------------------------------------------------*/
2510 /* geniCodeRightShift - gen i code for right shift */
2511 /*-----------------------------------------------------------------*/
2513 geniCodeRightShift (operand * left, operand * right)
2517 ic = newiCode (RIGHT_OP, left, right);
2518 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2520 return IC_RESULT (ic);
2523 /*-----------------------------------------------------------------*/
2524 /* geniCodeLogic- logic code */
2525 /*-----------------------------------------------------------------*/
2527 geniCodeLogic (operand * left, operand * right, int op)
2531 sym_link *rtype = operandType (right);
2532 sym_link *ltype = operandType (left);
2534 /* left is integral type and right is literal then
2535 check if the literal value is within bounds */
2536 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2538 checkConstantRange(ltype,
2539 OP_VALUE(right), "compare operation", 1);
2542 ctype = usualBinaryConversions (&left, &right);
2544 ic = newiCode (op, left, right);
2545 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2547 /* if comparing float
2548 and not a '==' || '!=' || '&&' || '||' (these
2550 if (IS_FLOAT(ctype) &&
2558 return IC_RESULT (ic);
2561 /*-----------------------------------------------------------------*/
2562 /* geniCodeUnary - for a a generic unary operation */
2563 /*-----------------------------------------------------------------*/
2565 geniCodeUnary (operand * op, int oper)
2567 iCode *ic = newiCode (oper, op, NULL);
2569 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2571 return IC_RESULT (ic);
2574 /*-----------------------------------------------------------------*/
2575 /* geniCodeConditional - geniCode for '?' ':' operation */
2576 /*-----------------------------------------------------------------*/
2578 geniCodeConditional (ast * tree,int lvl)
2581 symbol *falseLabel = newiTempLabel (NULL);
2582 symbol *exitLabel = newiTempLabel (NULL);
2583 operand *cond = ast2iCode (tree->left,lvl+1);
2584 operand *true, *false, *result;
2586 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2590 true = ast2iCode (tree->right->left,lvl+1);
2592 /* move the value to a new Operand */
2593 result = newiTempOperand (tree->right->ftype, 0);
2594 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2596 /* generate an unconditional goto */
2597 geniCodeGoto (exitLabel);
2599 /* now for the right side */
2600 geniCodeLabel (falseLabel);
2602 false = ast2iCode (tree->right->right,lvl+1);
2603 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2605 /* create the exit label */
2606 geniCodeLabel (exitLabel);
2611 /*-----------------------------------------------------------------*/
2612 /* geniCodeAssign - generate code for assignment */
2613 /*-----------------------------------------------------------------*/
2615 geniCodeAssign (operand * left, operand * right, int nosupdate)
2618 sym_link *ltype = operandType (left);
2619 sym_link *rtype = operandType (right);
2621 if (!left->isaddr && !IS_ITEMP (left))
2623 werror (E_LVALUE_REQUIRED, "assignment");
2627 /* left is integral type and right is literal then
2628 check if the literal value is within bounds */
2629 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2631 checkConstantRange(ltype,
2632 OP_VALUE(right), "= operation", 0);
2635 /* if the left & right type don't exactly match */
2636 /* if pointer set then make sure the check is
2637 done with the type & not the pointer */
2638 /* then cast rights type to left */
2640 /* first check the type for pointer assignement */
2641 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2642 compareType (ltype, rtype) <= 0)
2644 if (compareType (ltype->next, rtype) < 0)
2645 right = geniCodeCast (ltype->next, right, TRUE);
2647 else if (compareType (ltype, rtype) < 0)
2648 right = geniCodeCast (ltype, right, TRUE);
2650 /* if left is a true symbol & ! volatile
2651 create an assignment to temporary for
2652 the right & then assign this temporary
2653 to the symbol this is SSA . isn't it simple
2654 and folks have published mountains of paper on it */
2655 if (IS_TRUE_SYMOP (left) &&
2656 !isOperandVolatile (left, FALSE) &&
2657 isOperandGlobal (left))
2661 if (IS_TRUE_SYMOP (right))
2662 sym = OP_SYMBOL (right);
2663 ic = newiCode ('=', NULL, right);
2664 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2665 SPIL_LOC (right) = sym;
2669 ic = newiCode ('=', NULL, right);
2670 IC_RESULT (ic) = left;
2673 /* if left isgptr flag is set then support
2674 routine will be required */
2678 ic->nosupdate = nosupdate;
2682 /*-----------------------------------------------------------------*/
2683 /* geniCodeSEParms - generate code for side effecting fcalls */
2684 /*-----------------------------------------------------------------*/
2686 geniCodeSEParms (ast * parms,int lvl)
2691 if (parms->type == EX_OP && parms->opval.op == PARAM)
2693 geniCodeSEParms (parms->left,lvl);
2694 geniCodeSEParms (parms->right,lvl);
2698 /* hack don't like this but too lazy to think of
2700 if (IS_ADDRESS_OF_OP (parms))
2701 parms->left->lvalue = 1;
2703 if (IS_CAST_OP (parms) &&
2704 IS_PTR (parms->ftype) &&
2705 IS_ADDRESS_OF_OP (parms->right))
2706 parms->right->left->lvalue = 1;
2708 parms->opval.oprnd =
2709 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2711 parms->type = EX_OPERAND;
2714 /*-----------------------------------------------------------------*/
2715 /* geniCodeParms - generates parameters */
2716 /*-----------------------------------------------------------------*/
2718 geniCodeParms (ast * parms, value *argVals, int *stack,
2719 sym_link * fetype, symbol * func,int lvl)
2727 if (argVals==NULL) {
2729 argVals=FUNC_ARGS(func->type);
2732 /* if this is a param node then do the left & right */
2733 if (parms->type == EX_OP && parms->opval.op == PARAM)
2735 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2736 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2740 /* get the parameter value */
2741 if (parms->type == EX_OPERAND)
2742 pval = parms->opval.oprnd;
2745 /* maybe this else should go away ?? */
2746 /* hack don't like this but too lazy to think of
2748 if (IS_ADDRESS_OF_OP (parms))
2749 parms->left->lvalue = 1;
2751 if (IS_CAST_OP (parms) &&
2752 IS_PTR (parms->ftype) &&
2753 IS_ADDRESS_OF_OP (parms->right))
2754 parms->right->left->lvalue = 1;
2756 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2759 /* if register parm then make it a send */
2760 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2761 IFFUNC_ISBUILTIN(func->type))
2763 ic = newiCode (SEND, pval, NULL);
2764 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2769 /* now decide whether to push or assign */
2770 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2774 operand *top = operandFromSymbol (argVals->sym);
2775 /* clear useDef and other bitVectors */
2776 OP_USES (top) = OP_DEFS (top) = OP_SYMBOL(top)->clashes = NULL;
2777 geniCodeAssign (top, pval, 1);
2781 sym_link *p = operandType (pval);
2783 ic = newiCode (IPUSH, pval, NULL);
2785 /* update the stack adjustment */
2786 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2791 argVals=argVals->next;
2795 /*-----------------------------------------------------------------*/
2796 /* geniCodeCall - generates temp code for calling */
2797 /*-----------------------------------------------------------------*/
2799 geniCodeCall (operand * left, ast * parms,int lvl)
2803 sym_link *type, *etype;
2806 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2807 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2808 werror (E_FUNCTION_EXPECTED);
2812 /* take care of parameters with side-effecting
2813 function calls in them, this is required to take care
2814 of overlaying function parameters */
2815 geniCodeSEParms (parms,lvl);
2817 /* first the parameters */
2818 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2820 /* now call : if symbol then pcall */
2821 if (IS_OP_POINTER (left) || IS_ITEMP(left))
2822 ic = newiCode (PCALL, left, NULL);
2824 ic = newiCode (CALL, left, NULL);
2826 type = copyLinkChain (operandType (left)->next);
2827 etype = getSpec (type);
2828 SPEC_EXTR (etype) = 0;
2829 IC_RESULT (ic) = result = newiTempOperand (type, 1);
2833 /* stack adjustment after call */
2834 ic->parmBytes = stack;
2839 /*-----------------------------------------------------------------*/
2840 /* geniCodeReceive - generate intermediate code for "receive" */
2841 /*-----------------------------------------------------------------*/
2843 geniCodeReceive (value * args)
2845 /* for all arguments that are passed in registers */
2849 if (IS_REGPARM (args->etype))
2851 operand *opr = operandFromValue (args);
2853 symbol *sym = OP_SYMBOL (opr);
2856 /* we will use it after all optimizations
2857 and before liveRange calculation */
2858 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
2861 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
2862 options.stackAuto == 0 &&
2863 /* !TARGET_IS_DS390) */
2864 (!(options.model == MODEL_FLAT24)) )
2869 opl = newiTempOperand (args->type, 0);
2871 sym->reqv->key = sym->key;
2872 OP_SYMBOL (sym->reqv)->key = sym->key;
2873 OP_SYMBOL (sym->reqv)->isreqv = 1;
2874 OP_SYMBOL (sym->reqv)->islocal = 0;
2875 SPIL_LOC (sym->reqv) = sym;
2879 ic = newiCode (RECEIVE, NULL, NULL);
2880 currFunc->recvSize = getSize (sym->etype);
2881 IC_RESULT (ic) = opr;
2889 /*-----------------------------------------------------------------*/
2890 /* geniCodeFunctionBody - create the function body */
2891 /*-----------------------------------------------------------------*/
2893 geniCodeFunctionBody (ast * tree,int lvl)
2900 /* reset the auto generation */
2906 func = ast2iCode (tree->left,lvl+1);
2907 fetype = getSpec (operandType (func));
2909 savelineno = lineno;
2910 lineno = OP_SYMBOL (func)->lineDef;
2911 /* create an entry label */
2912 geniCodeLabel (entryLabel);
2913 lineno = savelineno;
2915 /* create a proc icode */
2916 ic = newiCode (FUNCTION, func, NULL);
2917 ic->lineno = OP_SYMBOL (func)->lineDef;
2921 /* for all parameters that are passed
2922 on registers add a "receive" */
2923 geniCodeReceive (tree->values.args);
2925 /* generate code for the body */
2926 ast2iCode (tree->right,lvl+1);
2928 /* create a label for return */
2929 geniCodeLabel (returnLabel);
2931 /* now generate the end proc */
2932 ic = newiCode (ENDFUNCTION, func, NULL);
2937 /*-----------------------------------------------------------------*/
2938 /* geniCodeReturn - gen icode for 'return' statement */
2939 /*-----------------------------------------------------------------*/
2941 geniCodeReturn (operand * op)
2945 /* if the operand is present force an rvalue */
2947 op = geniCodeRValue (op, FALSE);
2949 ic = newiCode (RETURN, op, NULL);
2953 /*-----------------------------------------------------------------*/
2954 /* geniCodeIfx - generates code for extended if statement */
2955 /*-----------------------------------------------------------------*/
2957 geniCodeIfx (ast * tree,int lvl)
2960 operand *condition = ast2iCode (tree->left,lvl+1);
2963 /* if condition is null then exit */
2967 condition = geniCodeRValue (condition, FALSE);
2969 cetype = getSpec (operandType (condition));
2970 /* if the condition is a literal */
2971 if (IS_LITERAL (cetype))
2973 if (floatFromVal (condition->operand.valOperand))
2975 if (tree->trueLabel)
2976 geniCodeGoto (tree->trueLabel);
2982 if (tree->falseLabel)
2983 geniCodeGoto (tree->falseLabel);
2990 if (tree->trueLabel)
2992 ic = newiCodeCondition (condition,
2997 if (tree->falseLabel)
2998 geniCodeGoto (tree->falseLabel);
3002 ic = newiCodeCondition (condition,
3009 ast2iCode (tree->right,lvl+1);
3012 /*-----------------------------------------------------------------*/
3013 /* geniCodeJumpTable - tries to create a jump table for switch */
3014 /*-----------------------------------------------------------------*/
3016 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3018 int min = 0, max = 0, t, cnt = 0;
3025 if (!tree || !caseVals)
3028 /* the criteria for creating a jump table is */
3029 /* all integer numbers between the maximum & minimum must */
3030 /* be present , the maximum value should not exceed 255 */
3031 min = max = (int) floatFromVal (vch = caseVals);
3032 sprintf (buffer, "_case_%d_%d",
3033 tree->values.switchVals.swNum,
3035 addSet (&labels, newiTempLabel (buffer));
3037 /* if there is only one case value then no need */
3038 if (!(vch = vch->next))
3043 if (((t = (int) floatFromVal (vch)) - max) != 1)
3045 sprintf (buffer, "_case_%d_%d",
3046 tree->values.switchVals.swNum,
3048 addSet (&labels, newiTempLabel (buffer));
3054 /* if the number of case statements <= 2 then */
3055 /* it is not economical to create the jump table */
3056 /* since two compares are needed for boundary conditions */
3057 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3060 if (tree->values.switchVals.swDefault)
3061 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3063 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3065 falseLabel = newiTempLabel (buffer);
3067 /* so we can create a jumptable */
3068 /* first we rule out the boundary conditions */
3069 /* if only optimization says so */
3070 if (!optimize.noJTabBoundary)
3072 sym_link *cetype = getSpec (operandType (cond));
3073 /* no need to check the lower bound if
3074 the condition is unsigned & minimum value is zero */
3075 if (!(min == 0 && SPEC_USIGN (cetype)))
3077 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3078 ic = newiCodeCondition (boundary, falseLabel, NULL);
3082 /* now for upper bounds */
3083 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3084 ic = newiCodeCondition (boundary, falseLabel, NULL);
3088 /* if the min is not zero then we no make it zero */
3091 cond = geniCodeSubtract (cond, operandFromLit (min));
3092 setOperandType (cond, UCHARTYPE);
3095 /* now create the jumptable */
3096 ic = newiCode (JUMPTABLE, NULL, NULL);
3097 IC_JTCOND (ic) = cond;
3098 IC_JTLABELS (ic) = labels;
3103 /*-----------------------------------------------------------------*/
3104 /* geniCodeSwitch - changes a switch to a if statement */
3105 /*-----------------------------------------------------------------*/
3107 geniCodeSwitch (ast * tree,int lvl)
3110 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3111 value *caseVals = tree->values.switchVals.swVals;
3112 symbol *trueLabel, *falseLabel;
3114 /* if we can make this a jump table */
3115 if (geniCodeJumpTable (cond, caseVals, tree))
3116 goto jumpTable; /* no need for the comparison */
3118 /* for the cases defined do */
3122 operand *compare = geniCodeLogic (cond,
3123 operandFromValue (caseVals),
3126 sprintf (buffer, "_case_%d_%d",
3127 tree->values.switchVals.swNum,
3128 (int) floatFromVal (caseVals));
3129 trueLabel = newiTempLabel (buffer);
3131 ic = newiCodeCondition (compare, trueLabel, NULL);
3133 caseVals = caseVals->next;
3138 /* if default is present then goto break else break */
3139 if (tree->values.switchVals.swDefault)
3140 sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
3142 sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
3144 falseLabel = newiTempLabel (buffer);
3145 geniCodeGoto (falseLabel);
3148 ast2iCode (tree->right,lvl+1);
3151 /*-----------------------------------------------------------------*/
3152 /* geniCodeInline - intermediate code for inline assembler */
3153 /*-----------------------------------------------------------------*/
3155 geniCodeInline (ast * tree)
3159 ic = newiCode (INLINEASM, NULL, NULL);
3160 IC_INLINE (ic) = tree->values.inlineasm;
3164 /*-----------------------------------------------------------------*/
3165 /* geniCodeArrayInit - intermediate code for array initializer */
3166 /*-----------------------------------------------------------------*/
3168 geniCodeArrayInit (ast * tree, operand *array)
3172 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3173 ic = newiCode (ARRAYINIT, array, NULL);
3174 IC_ARRAYILIST (ic) = tree->values.constlist;
3176 operand *left=newOperand(), *right=newOperand();
3177 left->type=right->type=SYMBOL;
3178 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3179 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3180 ic = newiCode (ARRAYINIT, left, right);
3185 /*-----------------------------------------------------------------*/
3186 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3187 /* particular case. Ie : assigning or dereferencing array or ptr */
3188 /*-----------------------------------------------------------------*/
3189 set * lvaluereqSet = NULL;
3190 typedef struct lvalItem
3197 /*-----------------------------------------------------------------*/
3198 /* addLvaluereq - add a flag for lvalreq for current ast level */
3199 /*-----------------------------------------------------------------*/
3200 void addLvaluereq(int lvl)
3202 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3205 addSetHead(&lvaluereqSet,lpItem);
3208 /*-----------------------------------------------------------------*/
3209 /* delLvaluereq - del a flag for lvalreq for current ast level */
3210 /*-----------------------------------------------------------------*/
3214 lpItem = getSet(&lvaluereqSet);
3215 if(lpItem) Safe_free(lpItem);
3217 /*-----------------------------------------------------------------*/
3218 /* clearLvaluereq - clear lvalreq flag */
3219 /*-----------------------------------------------------------------*/
3220 void clearLvaluereq()
3223 lpItem = peekSet(lvaluereqSet);
3224 if(lpItem) lpItem->req = 0;
3226 /*-----------------------------------------------------------------*/
3227 /* getLvaluereq - get the last lvalreq level */
3228 /*-----------------------------------------------------------------*/
3229 int getLvaluereqLvl()
3232 lpItem = peekSet(lvaluereqSet);
3233 if(lpItem) return lpItem->lvl;
3236 /*-----------------------------------------------------------------*/
3237 /* isLvaluereq - is lvalreq valid for this level ? */
3238 /*-----------------------------------------------------------------*/
3239 int isLvaluereq(int lvl)
3242 lpItem = peekSet(lvaluereqSet);
3243 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3247 /*-----------------------------------------------------------------*/
3248 /* ast2iCode - creates an icodeList from an ast */
3249 /*-----------------------------------------------------------------*/
3251 ast2iCode (ast * tree,int lvl)
3253 operand *left = NULL;
3254 operand *right = NULL;
3257 /* set the global variables for filename & line number */
3259 filename = tree->filename;
3261 lineno = tree->lineno;
3263 block = tree->block;
3265 scopeLevel = tree->level;
3267 if (tree->type == EX_VALUE)
3268 return operandFromValue (tree->opval.val);
3270 if (tree->type == EX_LINK)
3271 return operandFromLink (tree->opval.lnk);
3273 /* if we find a nullop */
3274 if (tree->type == EX_OP &&
3275 (tree->opval.op == NULLOP ||
3276 tree->opval.op == BLOCK))
3278 ast2iCode (tree->left,lvl+1);
3279 ast2iCode (tree->right,lvl+1);
3283 /* special cases for not evaluating */
3284 if (tree->opval.op != ':' &&
3285 tree->opval.op != '?' &&
3286 tree->opval.op != CALL &&
3287 tree->opval.op != IFX &&
3288 tree->opval.op != LABEL &&
3289 tree->opval.op != GOTO &&
3290 tree->opval.op != SWITCH &&
3291 tree->opval.op != FUNCTION &&
3292 tree->opval.op != INLINEASM)
3295 if (IS_ASSIGN_OP (tree->opval.op) ||
3296 IS_DEREF_OP (tree) ||
3297 (tree->opval.op == '&' && !tree->right) ||
3298 tree->opval.op == PTR_OP)
3301 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3302 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3305 left = operandFromAst (tree->left,lvl);
3307 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3308 left = geniCodeRValue (left, TRUE);
3312 left = operandFromAst (tree->left,lvl);
3314 if (tree->opval.op == INC_OP ||
3315 tree->opval.op == DEC_OP)
3318 right = operandFromAst (tree->right,lvl);
3323 right = operandFromAst (tree->right,lvl);
3327 /* now depending on the type of operand */
3328 /* this will be a biggy */
3329 switch (tree->opval.op)
3332 case '[': /* array operation */
3334 //sym_link *ltype = operandType (left);
3335 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3336 left = geniCodeRValue (left, FALSE);
3337 right = geniCodeRValue (right, TRUE);
3340 return geniCodeArray (left, right,lvl);
3342 case '.': /* structure dereference */
3343 if (IS_PTR (operandType (left)))
3344 left = geniCodeRValue (left, TRUE);
3346 left = geniCodeRValue (left, FALSE);
3348 return geniCodeStruct (left, right, tree->lvalue);
3350 case PTR_OP: /* structure pointer dereference */
3353 pType = operandType (left);
3354 left = geniCodeRValue (left, TRUE);
3356 setOClass (pType, getSpec (operandType (left)));
3359 return geniCodeStruct (left, right, tree->lvalue);
3361 case INC_OP: /* increment operator */
3363 return geniCodePostInc (left);
3365 return geniCodePreInc (right);
3367 case DEC_OP: /* decrement operator */
3369 return geniCodePostDec (left);
3371 return geniCodePreDec (right);
3373 case '&': /* bitwise and or address of operator */
3375 { /* this is a bitwise operator */
3376 left = geniCodeRValue (left, FALSE);
3377 right = geniCodeRValue (right, FALSE);
3378 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3381 return geniCodeAddressOf (left);
3383 case '|': /* bitwise or & xor */
3385 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3386 geniCodeRValue (right, FALSE),
3391 return geniCodeDivision (geniCodeRValue (left, FALSE),
3392 geniCodeRValue (right, FALSE));
3395 return geniCodeModulus (geniCodeRValue (left, FALSE),
3396 geniCodeRValue (right, FALSE));
3399 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3400 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3402 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3406 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3407 geniCodeRValue (right, FALSE));
3409 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3413 return geniCodeAdd (geniCodeRValue (left, FALSE),
3414 geniCodeRValue (right, FALSE),lvl);
3416 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3419 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3420 geniCodeRValue (right, FALSE));
3423 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3424 geniCodeRValue (right, FALSE));
3426 return geniCodeCast (operandType (left),
3427 geniCodeRValue (right, FALSE), FALSE);
3433 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3437 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3438 setOperandType (op, UCHARTYPE);
3449 return geniCodeLogic (geniCodeRValue (left, FALSE),
3450 geniCodeRValue (right, FALSE),
3453 return geniCodeConditional (tree,lvl);
3456 return operandFromLit (getSize (tree->right->ftype));
3460 sym_link *rtype = operandType (right);
3461 sym_link *ltype = operandType (left);
3462 if (IS_PTR (rtype) && IS_ITEMP (right)
3463 && right->isaddr && compareType (rtype->next, ltype) == 1)
3464 right = geniCodeRValue (right, TRUE);
3466 right = geniCodeRValue (right, FALSE);
3468 geniCodeAssign (left, right, 0);
3473 geniCodeAssign (left,
3474 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3476 geniCodeRValue (right, FALSE),FALSE), 0);
3480 geniCodeAssign (left,
3481 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3483 geniCodeRValue (right, FALSE)), 0);
3486 geniCodeAssign (left,
3487 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3489 geniCodeRValue (right, FALSE)), 0);
3492 sym_link *rtype = operandType (right);
3493 sym_link *ltype = operandType (left);
3494 if (IS_PTR (rtype) && IS_ITEMP (right)
3495 && right->isaddr && compareType (rtype->next, ltype) == 1)
3496 right = geniCodeRValue (right, TRUE);
3498 right = geniCodeRValue (right, FALSE);
3501 return geniCodeAssign (left,
3502 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3508 sym_link *rtype = operandType (right);
3509 sym_link *ltype = operandType (left);
3510 if (IS_PTR (rtype) && IS_ITEMP (right)
3511 && right->isaddr && compareType (rtype->next, ltype) == 1)
3513 right = geniCodeRValue (right, TRUE);
3517 right = geniCodeRValue (right, FALSE);
3520 geniCodeAssign (left,
3521 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3527 geniCodeAssign (left,
3528 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3530 geniCodeRValue (right, FALSE)), 0);
3533 geniCodeAssign (left,
3534 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3536 geniCodeRValue (right, FALSE)), 0);
3539 geniCodeAssign (left,
3540 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3542 geniCodeRValue (right, FALSE),
3544 operandType (left)), 0);
3547 geniCodeAssign (left,
3548 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3550 geniCodeRValue (right, FALSE),
3552 operandType (left)), 0);
3555 geniCodeAssign (left,
3556 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3558 geniCodeRValue (right, FALSE),
3560 operandType (left)), 0);
3562 return geniCodeRValue (right, FALSE);
3565 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3568 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3569 return ast2iCode (tree->right,lvl+1);
3572 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3573 return ast2iCode (tree->right,lvl+1);
3576 geniCodeFunctionBody (tree,lvl);
3580 geniCodeReturn (right);
3584 geniCodeIfx (tree,lvl);
3588 geniCodeSwitch (tree,lvl);
3592 geniCodeInline (tree);
3596 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3603 /*-----------------------------------------------------------------*/
3604 /* reverseICChain - gets from the list and creates a linkedlist */
3605 /*-----------------------------------------------------------------*/
3612 while ((loop = getSet (&iCodeChain)))
3624 /*-----------------------------------------------------------------*/
3625 /* iCodeFromAst - given an ast will convert it to iCode */
3626 /*-----------------------------------------------------------------*/
3628 iCodeFromAst (ast * tree)
3630 returnLabel = newiTempLabel ("_return");
3631 entryLabel = newiTempLabel ("_entry");
3633 return reverseiCChain ();