Added helper Macro SYM_SPIL_LOC
[fw/sdcc] / src / SDCCicode.h
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 ADDTOCHAIN(x) addSetHead(&iCodeChain,x)
54
55 #define LRFTYPE       sym_link *ltype = operandType(left), \
56                            *rtype = operandType(right) ;
57 #define LRETYPE       sym_link *letype= getSpec(ltype)   , \
58                            *retype= getSpec(rtype);
59 #define LRTYPE        LRFTYPE LRETYPE
60 #define IS_ITEMP(op)       (IS_SYMOP(op) && op->operand.symOperand->isitmp == 1)
61 #define IS_PARM(op)        (IS_SYMOP(op) && op->operand.symOperand->_isparm)
62 #define IS_ITEMPLBL(op)    (IS_ITEMP(op) && op->operand.symOperand->isilbl == 1);
63 #define IS_OP_VOLATILE(op) (IS_SYMOP(op) && op->isvolatile)
64 #define IS_OP_LITERAL(op)  (op && op->isLiteral)
65 #define IS_OP_GLOBAL(op)   (IS_SYMOP(op) && op->isGlobal)
66 #define IS_OP_POINTER(op)  (IS_SYMOP(op) && op->isPtr)
67 #define IS_OP_PARM(op)     (IS_SYMOP(op) && op->isParm)
68 #define OP_SYMBOL(op)      op->operand.symOperand
69 #define OP_SYM_TYPE(op)    op->operand.symOperand->type
70 #define OP_SYM_ETYPE(op)   op->operand.symOperand->etype
71 #define OP_VALUE(op)       op->operand.valOperand
72 #define SPIL_LOC(op)       op->operand.symOperand->usl.spillLoc
73 #define OP_LIVEFROM(op)    op->operand.symOperand->liveFrom
74 #define OP_LIVETO(op)      op->operand.symOperand->liveTo
75 #define OP_REQV(op)        op->operand.symOperand->reqv
76 #define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
77 #define SYM_SPIL_LOC(sym)  sym->usl.spillLoc
78
79 /* typedef for operand */
80 typedef struct operand
81   {
82     OPTYPE type;                /* type of operand */
83     unsigned int isaddr:1;      /* is an address   */
84     unsigned int isvolatile:1;  /* is a volatile operand */
85     unsigned int isGlobal:1;    /* is a global operand */
86     unsigned int isPtr:1;       /* is assigned a pointer */
87     unsigned int isGptr:1;      /* is a generic pointer  */
88     unsigned int isParm:1;      /* is a parameter        */
89     unsigned int isLiteral:1;   /* operand is literal    */
90
91     unsigned key;
92     union
93       {
94         struct symbol *symOperand;      /* operand is of type symbol */
95         struct value *valOperand;       /* operand is of type value  */
96         struct sym_link *typeOperand;   /* operand is of type typechain */
97       }
98     operand;
99
100     bitVect *usesDefs;          /* which definitions are used by this */
101     struct asmop *aop;          /* asm op for this operand */
102   }
103 operand;
104
105 /* definition for intermediate code */
106 #define IC_RESULT(x) (x)->ulrrcnd.lrr.result
107 #define IC_LEFT(x)   (x)->ulrrcnd.lrr.left
108 #define IC_RIGHT(x)  (x)->ulrrcnd.lrr.right
109 #define IC_COND(x)   (x)->ulrrcnd.cnd.condition
110 #define IC_TRUE(x)   (x)->ulrrcnd.cnd.trueLabel
111 #define IC_FALSE(x)  (x)->ulrrcnd.cnd.falseLabel
112 #define IC_LABEL(x)  (x)->argLabel.label
113 // jwk #define IC_ARGS(x)   (x)->argLabel.args
114 #define IC_JTCOND(x) (x)->ulrrcnd.jmpTab.condition
115 #define IC_JTLABELS(x) (x)->ulrrcnd.jmpTab.labels
116 #define IC_INLINE(x) (x)->inlineAsm
117 #define IC_ARRAYILIST(x) (x)->arrayInitList
118
119 typedef struct iCode
120   {
121     unsigned int op;            /* operation defined */
122     int key;                    /* running key for this iCode */
123     int seq;                    /* sequence number within routine */
124     short depth;                /* loop depth of this iCode */
125     short level;                /* scope level */
126     short block;                /* sequential block number */
127     unsigned nosupdate:1;       /* don't update spillocation with this */
128     unsigned generated:1;       /* code generated for this one */
129     unsigned parmPush:1;        /* parameter push Vs spill push */
130     unsigned supportRtn:1;      /* will cause a call to a support routine */
131     unsigned regsSaved:1;       /* registers have been saved */
132     unsigned bankSaved:1;       /* register bank has been saved */
133
134     struct iCode *next;         /* next in chain */
135     struct iCode *prev;         /* previous in chain */
136     set *movedFrom;             /* if this iCode gets moved to another block */
137     bitVect *rlive;             /* ranges that are live at this point */
138     int defKey;                 /* key for the operand being defined  */
139     bitVect *uses;              /* vector of key of used symbols      */
140     bitVect *rUsed;             /* registers used by this instruction */
141     bitVect *rMask;             /* registers in use during this instruction */
142     union
143       {
144         struct
145           {
146             operand *left;      /* left if any   */
147             operand *right;     /* right if any  */
148             operand *result;    /* result of this op */
149           }
150         lrr;
151
152         struct
153           {
154             operand *condition; /* if this is a conditional */
155             symbol *trueLabel;  /* true for conditional     */
156             symbol *falseLabel; /* false for conditional    */
157           }
158         cnd;
159
160         struct
161           {
162             operand *condition; /* condition for the jump */
163             set *labels;        /* ordered set of labels  */
164           }
165         jmpTab;
166
167       }
168     ulrrcnd;
169
170     union
171       {
172         symbol *label;          /* for a goto statement     */
173         // jwk value *args;            /* for a function */
174       }
175     argLabel;
176
177     char *inlineAsm;            /* pointer to inline assembler code */
178     literalList *arrayInitList; /* point to array initializer list. */
179
180     int lineno;                 /* file & lineno for debug information */
181     char *filename;
182     
183     int parmBytes;              /* if call/pcall, count of parameter bytes 
184                                    on stack */
185   }
186 iCode;
187
188 /* various functions associated to iCode */
189 typedef struct icodeFuncTable
190   {
191     int icode;
192     char *printName;
193     void (*iCodePrint) (FILE *, iCode *, char *);
194     iCode *(*iCodeCopy) (iCode *);
195   }
196 iCodeTable;
197
198 /* useful macros */
199 #define SKIP_IC2(x)  (x->op == GOTO     ||     \
200                       x->op == LABEL    ||     \
201                       x->op == FUNCTION ||     \
202                       x->op == INLINEASM ||    \
203                       x->op == ENDFUNCTION   )
204
205 #define SKIP_IC1(x)  (x->op == CALL     ||     \
206                       SKIP_IC2(x) )
207
208 #define SKIP_IC(x)   (x->op == PCALL    ||     \
209                       x->op == IPUSH    ||     \
210                       x->op == IPOP     ||     \
211                       x->op == JUMPTABLE ||    \
212                       x->op == RECEIVE  ||     \
213                       x->op == ARRAYINIT ||    \
214                       SKIP_IC1(x)||  \
215                       x->op == SEND         )
216
217 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
218                            x->op == '<'   || \
219                            x->op == '>'   || \
220                            x->op == LE_OP || \
221                            x->op == GE_OP || \
222                            x->op == NE_OP )
223
224 #define IS_TRUE_SYMOP(op) (op && IS_SYMOP(op) && !IS_ITEMP(op))
225
226 #define POINTER_SET(ic) ( ic && ic->op == '='           \
227                              && IS_ITEMP(IC_RESULT(ic)) \
228                              && IC_RESULT(ic)->isaddr )
229
230 #define POINTER_GET(ic) ( ic && ic->op == GET_VALUE_AT_ADDRESS  \
231                              &&  (IS_ITEMP(IC_LEFT(ic)) || IS_OP_LITERAL(IC_LEFT(ic)))\
232                              &&  IC_LEFT(ic)->isaddr )
233
234 #define IS_ARITHMETIC_OP(x) (x && (x->op == '+' || \
235                                    x->op == '-' || \
236                                    x->op == '/' || \
237                                    x->op == '*' || \
238                                    x->op == '%'))
239 #define IS_BITWISE_OP(x) (x && (x->op == BITWISEAND || \
240                                 x->op == '|'        || \
241                                 x->op == '^'))
242
243 #define ASSIGNMENT(ic) ( ic && ic->op == '=')
244
245 #define ASSIGN_SYM_TO_ITEMP(ic) (ic && ic->op == '=' && \
246                              IS_TRUE_SYMOP(IC_RIGHT(ic)) && \
247                              IS_ITEMP(IC_RESULT(ic)))
248
249 #define ASSIGN_ITEMP_TO_SYM(ic) (ic && ic->op == '=' && \
250                              IS_TRUE_SYMOP(IC_RESULT(ic)) && \
251                              IS_ITEMP(IC_RIGHT(ic)))
252
253 #define ASSIGN_ITEMP_TO_ITEMP(ic) (ic && ic->op == '=' &&\
254                                    !POINTER_SET(ic)    &&\
255                                    IS_ITEMP(IC_RIGHT(ic)) &&\
256                                    IS_ITEMP(IC_RESULT(ic)))
257
258 #define ADD_SUBTRACT_ITEMP(ic) (ic && (ic->op == '+' || ic->op == '-') && \
259                                 IS_ITEMP(IC_RESULT(ic)) && \
260                                 ( ( IS_ITEMP(IC_LEFT(ic)) ) ||  ( IS_SYMOP(IC_LEFT(ic)) ) ) && \
261                                   IS_OP_LITERAL(IC_RIGHT(ic)))
262
263 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
264                                 ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
265
266 #define IS_CAST_ICODE(ic) (ic && ic->op == CAST)
267 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
268 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
269 #define IS_ASSIGN_ICODE(ic) (ASSIGNMENT(ic) && !POINTER_SET(ic))
270
271 #define OP_DEFS(op) op->operand.symOperand->defs
272 #define OP_USES(op) op->operand.symOperand->uses
273 /*-----------------------------------------------------------------*/
274 /* forward references for functions                                */
275 /*-----------------------------------------------------------------*/
276 iCode *reverseiCChain ();
277 bool isOperandOnStack (operand *);
278 int isOperandVolatile (operand *, bool);
279 int isOperandGlobal (operand *);
280 void printiCChain (iCode *, FILE *);
281 operand *ast2iCode (ast *,int);
282 operand *geniCodeCast (sym_link *, operand *, bool);
283 operand *geniCodePtrPtrSubtract (operand *, operand *);
284 void initiCode ();
285 iCode *iCodeFromAst (ast *);
286 int isiCodeEqual (iCode *, iCode *);
287 int isOperandEqual (operand *, operand *);
288 iCodeTable *getTableEntry (int);
289 int isOperandLiteral (operand *);
290 operand *operandOperation (operand *, operand *, int, sym_link *);
291 double operandLitValue (operand *);
292 operand *operandFromLit (double);
293 operand *operandFromOperand (operand *);
294 int isParameterToCall (value *, operand *);
295 iCode *newiCodeLabelGoto (int, symbol *);
296 symbol *newiTemp (char *);
297 symbol *newiTempLabel (char *);
298 symbol *newiTempPreheaderLabel ();
299 iCode *newiCode (int, operand *, operand *);
300 sym_link *operandType (operand *);
301 operand *operandFromValue (value *);
302 operand *operandFromSymbol (symbol *);
303 sym_link *aggrToPtr (sym_link *, bool);
304 int piCode (void *, FILE *);
305 int printOperand (operand *, FILE *);
306 void setOperandType (operand *, sym_link *);
307 bool isOperandInFarSpace (operand *);
308 operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
309 iCode *copyiCode (iCode *);
310 operand *newiTempFromOp (operand *);
311 /*-----------------------------------------------------------------*/
312 /* declaration of exported variables                               */
313 /*-----------------------------------------------------------------*/
314 extern char *filename;
315 extern int lineno;
316 #endif