1 /*-------------------------------------------------------------------------
3 SDCCicode.h - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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
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.
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.
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 -------------------------------------------------------------------------*/
30 extern symbol
*returnLabel
;
31 extern symbol
*entryLabel
;
33 extern int operandKey
;
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)
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->svt.symOperand->isitmp == 1)
61 #define IS_PARM(op) (IS_SYMOP(op) && op->svt.symOperand->_isparm)
62 #define IS_ITEMPLBL(op) (IS_ITEMP(op) && op->svt.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_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
69 #define SYM_SPIL_LOC(sym) sym->usl.spillLoc
71 /* typedef for operand */
72 typedef struct operand
74 OPTYPE type
; /* type of operand */
75 unsigned int isaddr
:1; /* is an address */
76 unsigned int aggr2ptr
:2; /* 1: must change aggregate to pointer to aggregate */
77 /* 2: aggregate has been changed to pointer to aggregate */
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 unsigned int isConstElimnated
:1; /* if original const casted to non-const */
89 struct symbol
*symOperand
; /* operand is of type symbol */
90 struct value
*valOperand
; /* operand is of type value */
91 struct sym_link
*typeOperand
; /* operand is of type typechain */
95 bitVect
*usesDefs
; /* which definitions are used by this */
96 struct asmop
*aop
; /* asm op for this operand */
100 extern operand
*validateOpType (operand
* op
,
101 const char *macro
, const char *args
, OPTYPE type
, const char *file
, unsigned line
);
103 extern const operand
*validateOpTypeConst (const operand
* op
,
104 const char *macro
, const char *args
, OPTYPE type
, const char *file
, unsigned line
);
106 #define OP_SYMBOL(op) validateOpType(op, "OP_SYMBOL", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand
107 #define OP_SYMBOL_CONST(op) validateOpTypeConst(op, "OP_SYMBOL", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand
108 #define OP_VALUE(op) validateOpType(op, "OP_VALUE", #op, VALUE, __FILE__, __LINE__)->svt.valOperand
109 #define OP_VALUE_CONST(op) validateOpTypeConst(op, "OP_VALUE", #op, VALUE, __FILE__, __LINE__)->svt.valOperand
110 #define OP_SYM_TYPE(op) validateOpType(op, "OP_SYM_TYPE", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->type
111 #define OP_SYM_ETYPE(op) validateOpType(op, "OP_SYM_ETYPE", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->etype
112 #define SPIL_LOC(op) validateOpType(op, "SPIL_LOC", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->usl.spillLoc
113 #define OP_LIVEFROM(op) validateOpType(op, "OP_LIVEFROM", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->liveFrom
114 #define OP_LIVETO(op) validateOpType(op, "OP_LIVETO", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->liveTo
115 #define OP_REQV(op) validateOpType(op, "OP_REQV", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->reqv
116 #define OP_KEY(op) validateOpType(op, "OP_REQV", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->key
117 #define OP_TYPE(op) validateOpType(op, "OP_TYPE", #op, TYPE, __FILE__, __LINE__)->svt.typeOperand
119 /* definition for intermediate code */
120 #define IC_RESULT(x) (x)->result
121 #define IC_LEFT(x) (x)->left
122 #define IC_RIGHT(x) (x)->right
123 #define IC_COND(x) (x)->left // Not for use in new code. Some code still uses this, as it used to be separate from left.
124 #define IC_TRUE(x) (x)->ulrrcnd.cnd.trueLabel
125 #define IC_FALSE(x) (x)->ulrrcnd.cnd.falseLabel
126 #define IC_LABEL(x) (x)->label
127 #define IC_JTCOND(x) (x)->left // Not for use in new code. Some code still uses this, as it used to be separate from left.
128 #define IC_JTLABELS(x) (x)->ulrrcnd.jmpTab.labels
129 #define IC_INLINE(x) (x)->inlineAsm
130 #define IC_ARRAYILIST(x) (x)->arrayInitList
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 bool parmEscapeAlive
:1; /* At this iCode, a stack parameter, 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. */
152 unsigned inlined
:1; /* from an inlined function */
153 unsigned mergedElsewhere
:1; /* merged into another iCode during optimization */
155 struct iCode
*next
; /* next in chain */
156 struct iCode
*prev
; /* previous in chain */
157 set
*movedFrom
; /* if this iCode gets moved to another block */
158 bitVect
*rlive
; /* ranges that are live at this point */
159 int defKey
; /* key for the operand being defined */
160 bitVect
*uses
; /* vector of key of used symbols */
161 bitVect
*rUsed
; /* registers used by this instruction */
162 bitVect
*rMask
; /* registers in use during this instruction */
163 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) */
164 struct valinfos
*valinfos
; /* Information on the possible values of symbols just before this iCode. */
165 struct valinfo
*resultvalinfo
;/* Information on the possible values of the result. */
167 operand
*left
; // left if any
168 operand
*right
; // right if any
169 operand
*result
; // result of this op, if any
175 symbol
*trueLabel
; /* true for conditional */
176 symbol
*falseLabel
; /* false for conditional */
182 set
*labels
; /* ordered set of labels */
189 symbol
*label
; /* for a goto statement */
191 const char *inlineAsm
; /* pointer to inline assembler code */
192 literalList
*arrayInitList
; /* point to array initializer list. */
194 int lineno
; /* file & lineno for debug information */
197 int parmBytes
; /* if call/pcall, count of parameter bytes
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 */
205 struct ast
*tree
; /* ast node for this iCode (if not NULL) */
209 /* various functions associated to iCode */
210 typedef struct icodeFuncTable
214 void (*iCodePrint
) (struct dbuf_s
*, const iCode
*, char *);
215 iCode
*(*iCodeCopy
) (iCode
*);
220 #define SKIP_IC2(x) (x->op == GOTO || \
222 x->op == FUNCTION || \
223 x->op == INLINEASM || \
224 x->op == ENDFUNCTION )
226 #define SKIP_IC1(x) (x->op == CALL || \
229 #define SKIP_IC(x) (x->op == PCALL || \
231 x->op == IPUSH_VALUE_AT_ADDRESS || \
233 x->op == JUMPTABLE || \
234 x->op == RECEIVE || \
235 x->op == ARRAYINIT || \
237 x->op == CRITICAL || \
238 x->op == ENDCRITICAL || \
241 #define SKIP_IC3(x) (SKIP_IC2(x) || \
244 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
251 #define IS_TRUE_SYMOP(op) (op && IS_SYMOP(op) && !IS_ITEMP(op))
253 #define POINTER_SET(ic) ( ic && ic->op == '=' \
254 && (IS_ITEMP(IC_RESULT(ic)) || IS_OP_LITERAL(IC_RESULT(ic)))\
255 && IC_RESULT(ic)->isaddr )
257 #define POINTER_GET(ic) ( ic && ic->op == GET_VALUE_AT_ADDRESS \
258 && (IS_ITEMP(IC_LEFT(ic)) || IS_OP_LITERAL(IC_LEFT(ic)))\
259 && IC_LEFT(ic)->isaddr )
261 #define IS_ARITHMETIC_OP(x) (x && (x->op == '+' || \
266 #define IS_BITWISE_OP(x) (x && (x->op == BITWISEAND || \
270 #define IS_COMMUTATIVE(x) (x && (x->op == EQ_OP || \
274 x->op == BITWISEAND || \
278 #define ASSIGNMENT(ic) ( ic && ic->op == '=')
280 #define ASSIGN_SYM_TO_ITEMP(ic) (ic && ic->op == '=' && \
281 IS_TRUE_SYMOP(IC_RIGHT(ic)) && \
282 IS_ITEMP(IC_RESULT(ic)))
284 #define ASSIGN_ITEMP_TO_SYM(ic) (ic && ic->op == '=' && \
285 IS_TRUE_SYMOP(IC_RESULT(ic)) && \
286 IS_ITEMP(IC_RIGHT(ic)))
288 #define ASSIGN_ITEMP_TO_ITEMP(ic) (ic && ic->op == '=' &&\
290 IS_ITEMP(IC_RIGHT(ic)) &&\
291 IS_ITEMP(IC_RESULT(ic)))
293 #define ADD_SUBTRACT_ITEMP(ic) (ic && (ic->op == '+' || ic->op == '-') && \
294 IS_ITEMP(IC_RESULT(ic)) && \
295 ( ( IS_ITEMP(IC_LEFT(ic)) ) || ( IS_SYMOP(IC_LEFT(ic)) ) ) && \
296 IS_OP_LITERAL(IC_RIGHT(ic)))
298 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
299 ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
301 #define IS_CAST_ICODE(ic) (ic && ic->op == CAST)
302 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
303 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
304 #define IS_ASSIGN_ICODE(ic) (ASSIGNMENT(ic) && !POINTER_SET(ic))
306 #define OP_DEFS(op) validateOpType(op, "OP_DEFS", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->defs
307 #define OP_USES(op) validateOpType(op, "OP_USES", #op, SYMBOL, __FILE__, __LINE__)->svt.symOperand->uses
308 /*-----------------------------------------------------------------*/
309 /* forward references for functions */
310 /*-----------------------------------------------------------------*/
311 iCode
*reverseiCChain ();
312 bool isOperandOnStack (operand
*);
313 int isOperandVolatile (const operand
*, bool);
314 int isOperandGlobal (const operand
*);
315 void printiCChain (iCode
*, FILE *);
316 operand
*ast2iCode (ast
*, int);
317 operand
*geniCodePtrPtrSubtract (operand
*, operand
*);
319 iCode
*iCodeFromAst (ast
*);
320 int isiCodeEqual (iCode
*, iCode
*);
321 int isOperandEqual (const operand
*, const operand
*);
322 iCodeTable
*getTableEntry (int);
323 int isOperandLiteral (const operand
* const);
324 operand
*operandOperation (operand
*, operand
*, int, sym_link
*);
325 double operandLitValue (const operand
*);
326 unsigned long long operandLitValueUll (const operand
*);
327 operand
*operandFromLit (double);
328 operand
*operandFromOperand (operand
*);
329 int isParameterToCall (value
*, operand
*);
330 iCode
*newiCodeLabelGoto (int, symbol
*);
331 symbol
*newiTemp (const char *);
332 symbol
*newiTempLabel (const char *);
333 #define LOOPEXITLBL "loopExitLbl"
334 symbol
*newiTempLoopHeaderLabel (bool);
335 iCode
*newiCode (int, operand
*, operand
*);
336 sym_link
*operandType (const operand
*);
337 unsigned int operandSize (operand
*);
338 operand
*operandFromValue (value
*, bool convert_sym_to_ptr
);
339 operand
*operandFromSymbol (symbol
*, bool convert_sym_to_ptr
);
340 operand
*operandFromLink (sym_link
*);
341 sym_link
*aggrToPtr (sym_link
*, bool);
342 int aggrToPtrDclType (sym_link
*, bool);
343 void setOClass (sym_link
* ptr
, sym_link
* spec
);
344 int piCode (const iCode
*, FILE *);
345 int dbuf_printOperand (operand
*, struct dbuf_s
*);
346 int printOperand (operand
*, FILE *);
347 void setOperandType (operand
*, sym_link
*);
348 bool isOperandInFarSpace (operand
*);
349 bool isOperandInPagedSpace (operand
*);
350 bool isOperandInDirSpace (operand
*);
351 bool isOperandInBitSpace (operand
*);
352 bool isOperandInCodeSpace (operand
*);
353 operand
*opFromOpWithDU (operand
*, bitVect
*, bitVect
*);
354 iCode
*copyiCode (iCode
*);
355 operand
*newiTempOperand (sym_link
*, char);
356 operand
*newiTempFromOp (operand
*);
357 iCode
*getBuiltinParms (iCode
*, int *, operand
**);
358 int isiCodeInFunctionCall (iCode
*);
359 operand
*detachiCodeOperand (operand
**, iCode
*);
360 void attachiCodeOperand (operand
*, operand
**, iCode
*);
362 /*-----------------------------------------------------------------*/
363 /* declaration of exported variables */
364 /*-----------------------------------------------------------------*/
365 extern char *filename
;