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