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