1 /*-------------------------------------------------------------------------
2 
3   SDCCicode.h - intermediate code generation etc.
4                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 
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
9    later version.
10 
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.
15 
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.
19 
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 -------------------------------------------------------------------------*/
24 #include "SDCCbitv.h"
25 #include "SDCCset.h"
26 
27 #ifndef SDCCICODE_H
28 #define SDCCICODE_H 1
29 
30 extern symbol *returnLabel;
31 extern symbol *entryLabel;
32 extern int iCodeKey;
33 extern int operandKey;
34 
35 enum
36 {
37   CONDITIONAL = 0,
38   EXPRESSION,
39   STATEMENT,
40   LEAF
41 };
42 
43 typedef enum
44 {
45   SYMBOL = 1,
46   VALUE,
47   TYPE
48 }
49 OPTYPE;
50 
51 #define IS_SYMOP(op) (op && op->type == SYMBOL)
52 #define IS_VALOP(op) (op && op->type == VALUE)
53 #define IS_TYPOP(op) (op && op->type == TYPE)
54 
55 #define ADDTOCHAIN(x) addSetHead(&iCodeChain,x)
56 
57 #define LRFTYPE       sym_link *ltype = operandType(left), \
58                            *rtype = operandType(right) ;
59 #define LRETYPE       sym_link *letype= getSpec(ltype)   , \
60                            *retype= getSpec(rtype);
61 #define LRTYPE        LRFTYPE LRETYPE
62 #define IS_ITEMP(op)       (IS_SYMOP(op) && op->svt.symOperand->isitmp == 1)
63 #define IS_PARM(op)        (IS_SYMOP(op) && op->svt.symOperand->_isparm)
64 #define IS_ITEMPLBL(op)    (IS_ITEMP(op) && op->svt.symOperand->isilbl == 1)
65 #define IS_OP_VOLATILE(op) (IS_SYMOP(op) && op->isvolatile)
66 #define IS_OP_LITERAL(op)  (op && op->isLiteral)
67 #define IS_OP_GLOBAL(op)   (IS_SYMOP(op) && op->isGlobal)
68 #define IS_OP_POINTER(op)  (IS_SYMOP(op) && op->isPtr)
69 #define IS_OP_PARM(op)     (IS_SYMOP(op) && op->isParm)
70 #define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
71 #define SYM_SPIL_LOC(sym)  sym->usl.spillLoc
72 
73 /* typedef for operand */
74 typedef struct operand
75 {
76   OPTYPE type;                      /* type of operand */
77   unsigned int isaddr:1;            /* is an address   */
78   unsigned int aggr2ptr:2;          /* 1: must change aggregate to pointer to aggregate */
79   /* 2: aggregate has been changed to pointer to aggregate */
80   unsigned int isvolatile:1;        /* is a volatile operand */
81   unsigned int isGlobal:1;          /* is a global operand */
82   unsigned int isPtr:1;             /* is assigned a pointer */
83   unsigned int isGptr:1;            /* is a generic pointer  */
84   unsigned int isParm:1;            /* is a parameter        */
85   unsigned int isLiteral:1;         /* operand is literal    */
86   unsigned int isConstElimnated:1;  /* if original const casted to non-const */
87 
88   int key;
89   union
90   {
91     struct symbol *symOperand;      /* operand is of type symbol */
92     struct value *valOperand;       /* operand is of type value  */
93     struct sym_link *typeOperand;   /* operand is of type typechain */
94   }
95   svt;
96 
97   bitVect *usesDefs;                /* which definitions are used by this */
98   struct asmop *aop;                /* asm op for this operand */
99 }
100 operand;
101 
102 extern operand *validateOpType (operand * op,
103                                 const char *macro, const char *args, OPTYPE type, const char *file, unsigned line);
104 
105 extern const operand *validateOpTypeConst (const operand * op,
106                                            const char *macro, const char *args, OPTYPE type, const char *file, unsigned line);
107 
108 #define OP_SYMBOL(op)        validateOpType(op, "OP_SYMBOL", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand
109 #define OP_SYMBOL_CONST(op)  validateOpTypeConst(op, "OP_SYMBOL", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand
110 #define OP_VALUE(op)         validateOpType(op, "OP_VALUE", #op, VALUE, __FILE__, __LINE__)->svt.valOperand
111 #define OP_VALUE_CONST(op)   validateOpTypeConst(op, "OP_VALUE", #op, VALUE, __FILE__, __LINE__)->svt.valOperand
112 #define OP_SYM_TYPE(op)      validateOpType(op, "OP_SYM_TYPE", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->type
113 #define OP_SYM_ETYPE(op)     validateOpType(op, "OP_SYM_ETYPE", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->etype
114 #define SPIL_LOC(op)         validateOpType(op, "SPIL_LOC", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->usl.spillLoc
115 #define OP_LIVEFROM(op)      validateOpType(op, "OP_LIVEFROM", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->liveFrom
116 #define OP_LIVETO(op)        validateOpType(op, "OP_LIVETO", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->liveTo
117 #define OP_REQV(op)          validateOpType(op, "OP_REQV", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->reqv
118 #define OP_KEY(op)           validateOpType(op, "OP_REQV", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->key
119 #define OP_TYPE(op)          validateOpType(op, "OP_TYPE", #op, TYPE, __FILE__, __LINE__)->svt.typeOperand
120 
121 /* definition for intermediate code */
122 #define IC_RESULT(x)     (x)->ulrrcnd.lrr.result
123 #define IC_LEFT(x)       (x)->ulrrcnd.lrr.left
124 #define IC_RIGHT(x)      (x)->ulrrcnd.lrr.right
125 #define IC_COND(x)       (x)->ulrrcnd.cnd.condition
126 #define IC_TRUE(x)       (x)->ulrrcnd.cnd.trueLabel
127 #define IC_FALSE(x)      (x)->ulrrcnd.cnd.falseLabel
128 #define IC_LABEL(x)      (x)->label
129 #define IC_JTCOND(x)     (x)->ulrrcnd.jmpTab.condition
130 #define IC_JTLABELS(x)   (x)->ulrrcnd.jmpTab.labels
131 #define IC_INLINE(x)     (x)->inlineAsm
132 #define IC_ARRAYILIST(x) (x)->arrayInitList
133 
134 typedef struct iCode
135 {
136   unsigned int op;              /* operation defined */
137   int key;                      /* running key for this iCode */
138   int seq;                      /* sequence number within routine */
139   int seqPoint;                 /* sequence point */
140   short depth;                  /* loop depth of this iCode */
141   long level;                   /* scope level */
142   short block;                  /* sequential block number */
143   unsigned nosupdate:1;         /* don't update spillocation with this */
144   unsigned generated:1;         /* code generated for this one */
145   unsigned parmPush:1;          /* parameter push Vs spill push */
146   unsigned supportRtn:1;        /* will cause a call to a support routine */
147   unsigned regsSaved:1;         /* registers have been saved */
148   unsigned bankSaved:1;         /* register bank has been saved */
149   unsigned builtinSEND:1;       /* SEND for parameter of builtin function */
150   bool localEscapeAlive:1;      /* At this iCode, a local variable, a pointer to which has escaped (e.g. by having been stored in a global variable, cast to integer, passed to function) might be alive. */
151 
152   struct iCode *next;           /* next in chain */
153   struct iCode *prev;           /* previous in chain */
154   set *movedFrom;               /* if this iCode gets moved to another block */
155   bitVect *rlive;               /* ranges that are live at this point */
156   int defKey;                   /* key for the operand being defined  */
157   bitVect *uses;                /* vector of key of used symbols      */
158   bitVect *rUsed;               /* registers used by this instruction */
159   bitVect *rMask;               /* registers in use during this instruction */
160   bitVect *rSurv;               /* registers that survive this instruction (i.e. they are in use, it is not their last use and they are not in the return) */
161   union
162   {
163     struct
164     {
165       operand *left;            /* left if any   */
166       operand *right;           /* right if any  */
167       operand *result;          /* result of this op */
168     }
169     lrr;
170 
171     struct
172     {
173       operand *condition;       /* if this is a conditional */
174       symbol *trueLabel;        /* true for conditional     */
175       symbol *falseLabel;       /* false for conditional    */
176     }
177     cnd;
178 
179     struct
180     {
181       operand *condition;       /* condition for the jump */
182       set *labels;              /* ordered set of labels  */
183     }
184     jmpTab;
185 
186   }
187   ulrrcnd;
188 
189   symbol *label;                /* for a goto statement     */
190 
191   const char *inlineAsm;        /* pointer to inline assembler code */
192   literalList *arrayInitList;   /* point to array initializer list. */
193 
194   int lineno;                   /* file & lineno for debug information */
195   char *filename;
196 
197   int parmBytes;                /* if call/pcall, count of parameter bytes
198                                    on stack */
199   int argreg;                   /* argument regno for SEND/RECEIVE */
200   int eBBlockNum;               /* belongs to which eBBlock */
201   char riu;                     /* after ralloc, the registers in use */
202   float count;                  /* An execution count or probability */
203   float pcount;                 /* For propagation of count */
204 
205   struct ast *tree;             /* ast node for this iCode (if not NULL) */
206 }
207 iCode;
208 
209 /* various functions associated to iCode */
210 typedef struct icodeFuncTable
211 {
212   int icode;
213   char *printName;
214   void (*iCodePrint) (struct dbuf_s *, iCode *, char *);
215   iCode *(*iCodeCopy) (iCode *);
216 }
217 iCodeTable;
218 
219 /* useful macros */
220 #define SKIP_IC2(x)  (x->op == GOTO         ||    \
221                       x->op == LABEL        ||    \
222                       x->op == FUNCTION     ||    \
223                       x->op == INLINEASM    ||    \
224                       x->op == ENDFUNCTION  )
225 
226 #define SKIP_IC1(x)  (x->op == CALL         ||    \
227                       SKIP_IC2(x) )
228 
229 #define SKIP_IC(x)   (x->op == PCALL        ||    \
230                       x->op == IPUSH        ||    \
231                       x->op == IPOP         ||    \
232                       x->op == JUMPTABLE    ||    \
233                       x->op == RECEIVE      ||    \
234                       x->op == ARRAYINIT    ||    \
235                       SKIP_IC1(x)           ||    \
236                       x->op == CRITICAL     ||    \
237                       x->op == ENDCRITICAL  ||    \
238                       x->op == SEND         )
239 
240 #define SKIP_IC3(x) (SKIP_IC2(x)            ||    \
241                      x->op == JUMPTABLE )
242 
243 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
244                            x->op == '<'   || \
245                            x->op == '>'   || \
246                            x->op == LE_OP || \
247                            x->op == GE_OP || \
248                            x->op == NE_OP )
249 
250 #define IS_TRUE_SYMOP(op) (op && IS_SYMOP(op) && !IS_ITEMP(op))
251 
252 #define POINTER_SET(ic) ( ic && ic->op == '='           \
253                              && (IS_ITEMP(IC_RESULT(ic)) || IS_OP_LITERAL(IC_RESULT(ic)))\
254                              && IC_RESULT(ic)->isaddr )
255 
256 #define POINTER_GET(ic) ( ic && ic->op == GET_VALUE_AT_ADDRESS  \
257                              && (IS_ITEMP(IC_LEFT(ic)) || IS_OP_LITERAL(IC_LEFT(ic)))\
258                              && IC_LEFT(ic)->isaddr )
259 
260 #define IS_ARITHMETIC_OP(x) (x && (x->op == '+' || \
261                                    x->op == '-' || \
262                                    x->op == '/' || \
263                                    x->op == '*' || \
264                                    x->op == '%'))
265 #define IS_BITWISE_OP(x) (x && (x->op == BITWISEAND || \
266                                 x->op == '|'        || \
267                                 x->op == '^'))
268 
269 #define IS_COMMUTATIVE(x) (x && (x->op == EQ_OP      || \
270                                  x->op == NE_OP      || \
271                                  x->op == '+'        || \
272                                  x->op == '*'        || \
273                                  x->op == BITWISEAND || \
274                                  x->op == '|'        || \
275                                  x->op == '^'))
276 
277 #define ASSIGNMENT(ic) ( ic && ic->op == '=')
278 
279 #define ASSIGN_SYM_TO_ITEMP(ic) (ic && ic->op == '=' && \
280                              IS_TRUE_SYMOP(IC_RIGHT(ic)) && \
281                              IS_ITEMP(IC_RESULT(ic)))
282 
283 #define ASSIGN_ITEMP_TO_SYM(ic) (ic && ic->op == '=' && \
284                              IS_TRUE_SYMOP(IC_RESULT(ic)) && \
285                              IS_ITEMP(IC_RIGHT(ic)))
286 
287 #define ASSIGN_ITEMP_TO_ITEMP(ic) (ic && ic->op == '=' &&\
288                                    !POINTER_SET(ic)    &&\
289                                    IS_ITEMP(IC_RIGHT(ic)) &&\
290                                    IS_ITEMP(IC_RESULT(ic)))
291 
292 #define ADD_SUBTRACT_ITEMP(ic) (ic && (ic->op == '+' || ic->op == '-') && \
293                                 IS_ITEMP(IC_RESULT(ic)) && \
294                                 ( ( IS_ITEMP(IC_LEFT(ic)) ) ||  ( IS_SYMOP(IC_LEFT(ic)) ) ) && \
295                                   IS_OP_LITERAL(IC_RIGHT(ic)))
296 
297 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
298                                 ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
299 
300 #define IS_CAST_ICODE(ic) (ic && ic->op == CAST)
301 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
302 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
303 #define IS_ASSIGN_ICODE(ic) (ASSIGNMENT(ic) && !POINTER_SET(ic))
304 
305 #define OP_DEFS(op) validateOpType(op, "OP_DEFS", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->defs
306 #define OP_USES(op) validateOpType(op, "OP_USES", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->uses
307 /*-----------------------------------------------------------------*/
308 /* forward references for functions                                */
309 /*-----------------------------------------------------------------*/
310 iCode *reverseiCChain ();
311 bool isOperandOnStack (operand *);
312 int isOperandVolatile (const operand *, bool);
313 int isOperandGlobal (const operand *);
314 void printiCChain (iCode *, FILE *);
315 operand *ast2iCode (ast *, int);
316 operand *geniCodePtrPtrSubtract (operand *, operand *);
317 void initiCode ();
318 iCode *iCodeFromAst (ast *);
319 int isiCodeEqual (iCode *, iCode *);
320 int isOperandEqual (const operand *, const operand *);
321 iCodeTable *getTableEntry (int);
322 int isOperandLiteral (const operand * const);
323 operand *operandOperation (operand *, operand *, int, sym_link *);
324 double operandLitValue (const operand *);
325 unsigned long long operandLitValueUll (const operand *);
326 operand *operandFromLit (double);
327 operand *operandFromOperand (operand *);
328 int isParameterToCall (value *, operand *);
329 iCode *newiCodeLabelGoto (int, symbol *);
330 symbol *newiTemp (const char *);
331 symbol *newiTempLabel (const char *);
332 #define LOOPEXITLBL "loopExitLbl"
333 symbol *newiTempLoopHeaderLabel (bool);
334 iCode *newiCode (int, operand *, operand *);
335 sym_link *operandType (const operand *);
336 unsigned int operandSize (operand *);
337 operand *operandFromValue (value *);
338 operand *operandFromSymbol (symbol *);
339 operand *operandFromLink (sym_link *);
340 sym_link *aggrToPtr (sym_link *, bool);
341 int aggrToPtrDclType (sym_link *, bool);
342 void setOClass (sym_link * ptr, sym_link * spec);
343 int piCode (void *, FILE *);
344 int dbuf_printOperand (operand *, struct dbuf_s *);
345 int printOperand (operand *, FILE *);
346 void setOperandType (operand *, sym_link *);
347 bool isOperandInFarSpace (operand *);
348 bool isOperandInPagedSpace (operand *);
349 bool isOperandInDirSpace (operand *);
350 bool isOperandInBitSpace (operand *);
351 bool isOperandInCodeSpace (operand *);
352 operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
353 iCode *copyiCode (iCode *);
354 operand *newiTempOperand (sym_link *, char);
355 operand *newiTempFromOp (operand *);
356 iCode *getBuiltinParms (iCode *, int *, operand **);
357 int isiCodeInFunctionCall (iCode *);
358 /*-----------------------------------------------------------------*/
359 /* declaration of exported variables                               */
360 /*-----------------------------------------------------------------*/
361 extern char *filename;
362 extern int lineno;
363 #endif
364 
365