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 ;
47 #define IS_SYMOP(op) (op && op->type == SYMBOL)
48 #define ADDTOCHAIN(x) addSetHead(&iCodeChain,x)
50 #define LRFTYPE link *ltype = operandType(left), \
51 *rtype = operandType(right) ;
52 #define LRETYPE link *letype= getSpec(ltype) , \
53 *retype= getSpec(rtype);
54 #define LRTYPE LRFTYPE LRETYPE
55 #define IS_ITEMP(op) (IS_SYMOP(op) && op->operand.symOperand->isitmp == 1)
56 #define IS_PARM(op) (IS_SYMOP(op) && op->operand.symOperand->_isparm)
57 #define IS_ITEMPLBL(op) (IS_ITEMP(op) && op->operand.symOperand->isilbl == 1);
58 #define IS_OP_VOLATILE(op) (IS_SYMOP(op) && op->isvolatile)
59 #define IS_OP_LITERAL(op) (op && op->isLiteral)
60 #define IS_OP_GLOBAL(op) (IS_SYMOP(op) && op->isGlobal)
61 #define IS_OP_POINTER(op) (IS_SYMOP(op) && op->isPtr)
62 #define IS_OP_PARM(op) (IS_SYMOP(op) && op->isParm)
63 #define OP_SYMBOL(op) op->operand.symOperand
64 #define OP_SYM_TYPE(op) op->operand.symOperand->type
65 #define OP_SYM_ETYPE(op) op->operand.symOperand->etype
66 #define SPIL_LOC(op) op->operand.symOperand->usl.spillLoc
67 #define OP_LIVEFROM(op) op->operand.symOperand->liveFrom
68 #define OP_LIVETO(op) op->operand.symOperand->liveTo
69 #define OP_REQV(op) op->operand.symOperand->reqv
70 #define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
72 /* typedef for operand */
73 typedef struct operand {
74 OPTYPE type; /* type of operand */
75 unsigned int isaddr : 1; /* is an address */
76 unsigned int isvolatile: 1; /* is a volatile operand */
77 unsigned int isGlobal :1 ; /* is a global operand */
78 unsigned int isPtr :1 ; /* is assigned a pointer */
79 unsigned int isGptr :1 ; /* is a generic pointer */
80 unsigned int isParm :1 ; /* is a parameter */
81 unsigned int isLiteral:1 ; /* operand is literal */
82 unsigned int noSpilLoc:1 ; /* cannot be assigned a spil location */
87 struct symbol *symOperand ; /* operand is of type symbol */
88 struct value *valOperand ; /* operand is of type value */
89 struct link *typeOperand; /* operand is of type typechain */
92 bitVect *usesDefs; /* which definitions are used by this */
93 struct asmop *aop ; /* asm op for this operand */
96 /* definition for intermediate code */
97 #define IC_RESULT(x) x->ulrrcnd.lrr.result
98 #define IC_LEFT(x) x->ulrrcnd.lrr.left
99 #define IC_RIGHT(x) x->ulrrcnd.lrr.right
100 #define IC_COND(x) x->ulrrcnd.cnd.condition
101 #define IC_TRUE(x) x->ulrrcnd.cnd.trueLabel
102 #define IC_FALSE(x) x->ulrrcnd.cnd.falseLabel
103 #define IC_LABEL(x) x->argLabel.label
104 #define IC_ARGS(x) x->argLabel.args
105 #define IC_JTCOND(x) x->ulrrcnd.jmpTab.condition
106 #define IC_JTLABELS(x) x->ulrrcnd.jmpTab.labels
107 #define IC_INLINE(x) x->inlineAsm
111 unsigned int op ; /* operation defined */
112 int key ; /* running key for this iCode */
113 int seq ; /* sequence number within routine */
114 short depth ; /* loop depth of this iCode */
115 short level ; /* scope level */
116 short block ; /* sequential block number */
117 unsigned nosupdate:1; /* don't update spillocation with this */
118 unsigned generated:1; /* code generated for this one */
119 unsigned parmPush :1; /* parameter push Vs spill push */
120 unsigned supportRtn:1; /* will cause a call to a support routine */
121 unsigned regsSaved:1 ; /* registers have been saved */
122 unsigned bankSaved:1 ; /* register bank has been saved */
124 struct iCode *next ; /* next in chain */
125 struct iCode *prev ; /* previous in chain */
126 set *movedFrom; /* if this iCode gets moved to another block */
127 bitVect *rlive ; /* ranges that are live at this point */
128 int defKey ; /* key for the operand being defined */
129 bitVect *uses ; /* vector of key of used symbols */
130 bitVect *rUsed ; /* registers used by this instruction */
131 bitVect *rMask ; /* registers in use during this instruction */
134 operand *left ; /* left if any */
135 operand *right ; /* right if any */
136 operand *result ; /* result of this op */
140 operand *condition ; /* if this is a conditional */
141 symbol *trueLabel ; /* true for conditional */
142 symbol *falseLabel; /* false for conditional */
146 operand *condition ; /* condition for the jump */
147 set *labels ; /* ordered set of labels */
153 symbol *label ; /* for a goto statement */
157 char *inlineAsm ; /* pointer to inline assembler code */
159 int lineno ; /* file & lineno for debug information */
163 /* various functions associated to iCode */
164 typedef struct icodeFuncTable
168 void (*iCodePrint)(FILE *,iCode *,char *) ;
169 iCode * (*iCodeCopy)(iCode *) ;
173 #define SKIP_IC2(x) (x->op == GOTO || \
175 x->op == FUNCTION || \
176 x->op == INLINEASM || \
177 x->op == ENDFUNCTION )
179 #define SKIP_IC1(x) (x->op == CALL || \
182 #define SKIP_IC(x) (x->op == PCALL || \
185 x->op == JUMPTABLE || \
186 x->op == RECEIVE || \
190 #define IS_CONDITIONAL(x) (x->op == EQ_OP || \
197 #define IS_TRUE_SYMOP(op) (op && IS_SYMOP(op) && !IS_ITEMP(op))
199 #define POINTER_SET(ic) ( ic && ic->op == '=' \
200 && IS_ITEMP(IC_RESULT(ic)) \
201 && IC_RESULT(ic)->isaddr )
203 #define POINTER_GET(ic) ( ic && ic->op == GET_VALUE_AT_ADDRESS \
204 && (IS_ITEMP(IC_LEFT(ic)) || IS_OP_LITERAL(IC_LEFT(ic)))\
205 && IC_LEFT(ic)->isaddr )
207 #define IS_ARITHMETIC_OP(x) (x && (x->op == '+' || \
212 #define IS_BITWISE_OP(x) (x && (x->op == BITWISEAND || \
216 #define ASSIGNMENT(ic) ( ic && ic->op == '=')
218 #define ASSIGN_SYM_TO_ITEMP(ic) (ic && ic->op == '=' && \
219 IS_TRUE_SYMOP(IC_RIGHT(ic)) && \
220 IS_ITEMP(IC_RESULT(ic)))
222 #define ASSIGN_ITEMP_TO_SYM(ic) (ic && ic->op == '=' && \
223 IS_TRUE_SYMOP(IC_RESULT(ic)) && \
224 IS_ITEMP(IC_RIGHT(ic)))
226 #define ASSIGN_ITEMP_TO_ITEMP(ic) (ic && ic->op == '=' &&\
228 IS_ITEMP(IC_RIGHT(ic)) &&\
229 IS_ITEMP(IC_RESULT(ic)))
231 #define ADD_SUBTRACT_ITEMP(ic) (ic && (ic->op == '+' || ic->op == '-') && \
232 IS_ITEMP(IC_RESULT(ic)) && \
233 ( ( IS_ITEMP(IC_LEFT(ic)) ) || ( IS_SYMOP(IC_LEFT(ic)) ) ) && \
234 IS_OP_LITERAL(IC_RIGHT(ic)))
236 #define ASSIGNMENT_TO_SELF(ic) (!POINTER_SET(ic) && !POINTER_GET(ic) && \
237 ic->op == '=' && IC_RESULT(ic)->key == IC_RIGHT(ic)->key )
239 #define SET_ISADDR(op,v) {op = operandFromOperand(op); op->isaddr = v;}
240 #define SET_RESULT_RIGHT(ic) {SET_ISADDR(IC_RIGHT(ic),0); SET_ISADDR(IC_RESULT(ic),0);}
242 #define OP_DEFS(op) op->operand.symOperand->defs
243 #define OP_USES(op) op->operand.symOperand->uses
244 /*-----------------------------------------------------------------*/
245 /* forward references for functions */
246 /*-----------------------------------------------------------------*/
247 iCode *reverseiCChain ( );
248 int isOperandVolatile (operand *,bool);
249 int isOperandGlobal (operand *);
250 void printiCChain ( iCode * , FILE *);
251 operand *ast2iCode ( ast *);
252 operand *geniCodeCast ( link *, operand *,bool);
253 operand *geniCodePtrPtrSubtract (operand *, operand *);
255 iCode *iCodeFromAst ( ast * );
256 int isiCodeEqual ( iCode *,iCode *) ;
257 int isOperandEqual ( operand *, operand *);
258 iCodeTable *getTableEntry (int );
259 int isOperandLiteral (operand *);
260 operand *operandOperation (operand *,operand *,int,link *);
261 double operandLitValue ( operand * );
262 operand *operandFromLit (float);
263 operand *operandFromOperand(operand *);
264 int isParameterToCall (value *,operand *);
265 iCode *newiCodeLabelGoto (int , symbol *);
266 symbol *newiTemp(char *);
267 symbol *newiTempLabel (char *);
268 symbol *newiTempPreheaderLabel ();
269 iCode *newiCode (int, operand *, operand *);
270 link *operandType(operand *);
271 operand *operandFromValue (value *);
272 operand *operandFromSymbol(symbol *);
273 link *aggrToPtr ( link *, bool);
274 int piCode (void *, FILE * );
275 int printOperand (operand *,FILE *);
276 void setOperandType (operand *, link *);
277 bool isOperandInFarSpace (operand *);
278 operand *opFromOpWithDU (operand *,bitVect *,bitVect *);
279 iCode *copyiCode (iCode *);
280 operand *newiTempFromOp( operand *);
281 /*-----------------------------------------------------------------*/
282 /* declaration of exported variables */
283 /*-----------------------------------------------------------------*/
284 extern char *filename;