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