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 ADDTOCHAIN(x) addSetHead(&iCodeChain,x)
54 #define LRFTYPE sym_link *ltype = operandType(left), \
55 *rtype = operandType(right) ;
56 #define LRETYPE sym_link *letype= getSpec(ltype) , \
57 *retype= getSpec(rtype);
58 #define LRTYPE LRFTYPE LRETYPE
59 #define IS_ITEMP(op) (IS_SYMOP(op) && op->operand.symOperand->isitmp == 1)
60 #define IS_PARM(op) (IS_SYMOP(op) && op->operand.symOperand->_isparm)
61 #define IS_ITEMPLBL(op) (IS_ITEMP(op) && op->operand.symOperand->isilbl == 1);
62 #define IS_OP_VOLATILE(op) (IS_SYMOP(op) && op->isvolatile)
63 #define IS_OP_LITERAL(op) (op && op->isLiteral)
64 #define IS_OP_GLOBAL(op) (IS_SYMOP(op) && op->isGlobal)
65 #define IS_OP_POINTER(op) (IS_SYMOP(op) && op->isPtr)
66 #define IS_OP_PARM(op) (IS_SYMOP(op) && op->isParm)
67 #define OP_SYMBOL(op) op->operand.symOperand
68 #define OP_SYM_TYPE(op) op->operand.symOperand->type
69 #define OP_SYM_ETYPE(op) op->operand.symOperand->etype
70 #define SPIL_LOC(op) op->operand.symOperand->usl.spillLoc
71 #define OP_LIVEFROM(op) op->operand.symOperand->liveFrom
72 #define OP_LIVETO(op) op->operand.symOperand->liveTo
73 #define OP_REQV(op) op->operand.symOperand->reqv
74 #define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
76 /* typedef for operand */
77 typedef struct operand
79 OPTYPE type; /* type of operand */
80 unsigned int isaddr:1; /* is an address */
81 unsigned int isvolatile:1; /* is a volatile operand */
82 unsigned int isGlobal:1; /* is a global operand */
83 unsigned int isPtr:1; /* is assigned a pointer */
84 unsigned int isGptr:1; /* is a generic pointer */
85 unsigned int isParm:1; /* is a parameter */
86 unsigned int isLiteral:1; /* operand is literal */
87 unsigned int noSpilLoc:1; /* cannot be assigned a spil location */
92 struct symbol *symOperand; /* operand is of type symbol */
93 struct value *valOperand; /* operand is of type value */
94 struct sym_link *typeOperand; /* operand is of type typechain */
98 bitVect *usesDefs; /* which definitions are used by this */
99 struct asmop *aop; /* asm op for this operand */
103 /* definition for intermediate code */
104 #define IC_RESULT(x) (x)->ulrrcnd.lrr.result
105 #define IC_LEFT(x) (x)->ulrrcnd.lrr.left
106 #define IC_RIGHT(x) (x)->ulrrcnd.lrr.right
107 #define IC_COND(x) (x)->ulrrcnd.cnd.condition
108 #define IC_TRUE(x) (x)->ulrrcnd.cnd.trueLabel
109 #define IC_FALSE(x) (x)->ulrrcnd.cnd.falseLabel
110 #define IC_LABEL(x) (x)->argLabel.label
111 #define IC_ARGS(x) (x)->argLabel.args
112 #define IC_JTCOND(x) (x)->ulrrcnd.jmpTab.condition
113 #define IC_JTLABELS(x) (x)->ulrrcnd.jmpTab.labels
114 #define IC_INLINE(x) (x)->inlineAsm
118 unsigned int op; /* operation defined */
119 int key; /* running key for this iCode */
120 int seq; /* sequence number within routine */
121 short depth; /* loop depth of this iCode */
122 short level; /* scope level */
123 short block; /* sequential block number */
124 unsigned nosupdate:1; /* don't update spillocation with this */
125 unsigned generated:1; /* code generated for this one */
126 unsigned parmPush:1; /* parameter push Vs spill push */
127 unsigned supportRtn:1; /* will cause a call to a support routine */
128 unsigned regsSaved:1; /* registers have been saved */
129 unsigned bankSaved:1; /* register bank has been saved */
131 struct iCode *next; /* next in chain */
132 struct iCode *prev; /* previous in chain */
133 set *movedFrom; /* if this iCode gets moved to another block */
134 bitVect *rlive; /* ranges that are live at this point */
135 int defKey; /* key for the operand being defined */
136 bitVect *uses; /* vector of key of used symbols */
137 bitVect *rUsed; /* registers used by this instruction */
138 bitVect *rMask; /* registers in use during this instruction */
143 operand *left; /* left if any */
144 operand *right; /* right if any */
145 operand *result; /* result of this op */
151 operand *condition; /* if this is a conditional */
152 symbol *trueLabel; /* true for conditional */
153 symbol *falseLabel; /* false for conditional */
159 operand *condition; /* condition for the jump */
160 set *labels; /* ordered set of labels */
169 symbol *label; /* for a goto statement */
174 char *inlineAsm; /* pointer to inline assembler code */
176 int lineno; /* file & lineno for debug information */
179 int parmBytes; /* if call/pcall, count of parameter bytes
184 /* various functions associated to iCode */
185 typedef struct icodeFuncTable
189 void (*iCodePrint) (FILE *, iCode *, char *);
190 iCode *(*iCodeCopy) (iCode *);
195 #define SKIP_IC2(x) (x->op == GOTO || \
197 x->op == FUNCTION || \
198 x->op == INLINEASM || \
199 x->op == ENDFUNCTION )
201 #define SKIP_IC1(x) (x->op == CALL || \
204 #define SKIP_IC(x) (x->op == PCALL || \
207 x->op == JUMPTABLE || \
208 x->op == RECEIVE || \
212 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
219 #define IS_TRUE_SYMOP(op) (op && IS_SYMOP(op) && !IS_ITEMP(op))
221 #define POINTER_SET(ic) ( ic && ic->op == '=' \
222 && IS_ITEMP(IC_RESULT(ic)) \
223 && IC_RESULT(ic)->isaddr )
225 #define POINTER_GET(ic) ( ic && ic->op == GET_VALUE_AT_ADDRESS \
226 && (IS_ITEMP(IC_LEFT(ic)) || IS_OP_LITERAL(IC_LEFT(ic)))\
227 && IC_LEFT(ic)->isaddr )
229 #define IS_ARITHMETIC_OP(x) (x && (x->op == '+' || \
234 #define IS_BITWISE_OP(x) (x && (x->op == BITWISEAND || \
238 #define ASSIGNMENT(ic) ( ic && ic->op == '=')
240 #define ASSIGN_SYM_TO_ITEMP(ic) (ic && ic->op == '=' && \
241 IS_TRUE_SYMOP(IC_RIGHT(ic)) && \
242 IS_ITEMP(IC_RESULT(ic)))
244 #define ASSIGN_ITEMP_TO_SYM(ic) (ic && ic->op == '=' && \
245 IS_TRUE_SYMOP(IC_RESULT(ic)) && \
246 IS_ITEMP(IC_RIGHT(ic)))
248 #define ASSIGN_ITEMP_TO_ITEMP(ic) (ic && ic->op == '=' &&\
250 IS_ITEMP(IC_RIGHT(ic)) &&\
251 IS_ITEMP(IC_RESULT(ic)))
253 #define ADD_SUBTRACT_ITEMP(ic) (ic && (ic->op == '+' || ic->op == '-') && \
254 IS_ITEMP(IC_RESULT(ic)) && \
255 ( ( IS_ITEMP(IC_LEFT(ic)) ) || ( IS_SYMOP(IC_LEFT(ic)) ) ) && \
256 IS_OP_LITERAL(IC_RIGHT(ic)))
258 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
259 ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
261 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
262 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
264 #define OP_DEFS(op) op->operand.symOperand->defs
265 #define OP_USES(op) op->operand.symOperand->uses
266 /*-----------------------------------------------------------------*/
267 /* forward references for functions */
268 /*-----------------------------------------------------------------*/
269 iCode *reverseiCChain ();
270 bool isOperandOnStack (operand *);
271 int isOperandVolatile (operand *, bool);
272 int isOperandGlobal (operand *);
273 void printiCChain (iCode *, FILE *);
274 operand *ast2iCode (ast *,int);
275 operand *geniCodeCast (sym_link *, operand *, bool);
276 operand *geniCodePtrPtrSubtract (operand *, operand *);
278 iCode *iCodeFromAst (ast *);
279 int isiCodeEqual (iCode *, iCode *);
280 int isOperandEqual (operand *, operand *);
281 iCodeTable *getTableEntry (int);
282 int isOperandLiteral (operand *);
283 operand *operandOperation (operand *, operand *, int, sym_link *);
284 double operandLitValue (operand *);
285 operand *operandFromLit (double);
286 operand *operandFromOperand (operand *);
287 int isParameterToCall (value *, operand *);
288 iCode *newiCodeLabelGoto (int, symbol *);
289 symbol *newiTemp (char *);
290 symbol *newiTempLabel (char *);
291 symbol *newiTempPreheaderLabel ();
292 iCode *newiCode (int, operand *, operand *);
293 sym_link *operandType (operand *);
294 operand *operandFromValue (value *);
295 operand *operandFromSymbol (symbol *);
296 sym_link *aggrToPtr (sym_link *, bool);
297 int piCode (void *, FILE *);
298 int printOperand (operand *, FILE *);
299 void setOperandType (operand *, sym_link *);
300 bool isOperandInFarSpace (operand *);
301 operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
302 iCode *copyiCode (iCode *);
303 operand *newiTempFromOp (operand *);
304 /*-----------------------------------------------------------------*/
305 /* declaration of exported variables */
306 /*-----------------------------------------------------------------*/
307 extern char *filename;