* src/vm/jit/jit.c: Moved to .cpp.
[cacao.git] / src / vm / jit / ir / instruction.hpp
1 /* src/vm/jit/ir/instruction.hpp - IR instruction
2
3    Copyright (C) 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #ifndef _INSTRUCTION_HPP
27 #define _INSTRUCTION_HPP
28
29 // Forward typedefs.
30 typedef struct instruction instruction;
31 typedef struct insinfo_inline insinfo_inline;
32
33
34 #include "config.h"
35
36 #include <stdint.h>
37
38 #include "vm/descriptor.h"
39
40 #include "vm/jit/jit.hpp"
41 #include "vm/jit/replace.h"
42
43 #include "vm/jit/ir/icmd.hpp"
44
45
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49
50 // Instruction structure.
51
52 /* branch_target_t: used in TABLESWITCH tables */
53
54 typedef union {
55     int32_t                    insindex; /* used in parse                     */
56     basicblock                *block;    /* valid after parse                 */
57 } branch_target_t;
58
59 /* lookup_target_t: used in LOOKUPSWITCH tables */
60
61 typedef struct {
62     int32_t                    value;    /* case value                        */
63     branch_target_t            target;   /* branch target, see above          */
64 } lookup_target_t;
65
66 /*** s1 operand ***/
67
68 typedef union {
69         int32_t                    varindex;
70         int32_t                    argcount;
71 } s1_operand_t;
72
73 /*** s2 operand ***/
74
75 typedef union {
76         int32_t                    varindex;
77         int32_t                   *args;
78     classref_or_classinfo      c;
79     unresolved_class          *uc;
80     uintptr_t                  constval;         /* for PUT*CONST             */
81     int32_t                    tablelow;         /* for TABLESWITCH           */
82     uint32_t                   lookupcount;      /* for LOOKUPSWITCH          */
83         int32_t                    retaddrnr;        /* for ASTORE                */
84         instruction              **iargs;            /* for PHI                   */
85 } s2_operand_t;
86
87 /*** s3 operand ***/
88
89 typedef union {
90         int32_t                    varindex;
91     uintptr_t                  constval;
92     classref_or_classinfo      c;
93     constant_FMIref           *fmiref;
94     unresolved_method         *um;
95     unresolved_field          *uf;
96     insinfo_inline            *inlineinfo;       /* for INLINE_START/END      */
97     int32_t                    tablehigh;        /* for TABLESWITCH           */
98     branch_target_t            lookupdefault;    /* for LOOKUPSWITCH          */
99     branch_target_t            jsrtarget;        /* for JSR                   */
100         int32_t                    javaindex;        /* for *STORE                */
101     struct builtintable_entry *bte;
102 } s3_operand_t;
103
104 /*** val operand ***/
105
106 typedef union {
107     int32_t                   i;
108     int64_t                   l;
109     float                     f;
110     double                    d;
111     void                     *anyptr;
112     java_handle_t            *stringconst;       /* for ACONST with string    */
113     classref_or_classinfo     c;                 /* for ACONST with class     */
114 } val_operand_t;
115
116 /*** dst operand ***/
117
118 typedef union {
119         int32_t                    varindex;
120     basicblock                *block;       /* valid after parse              */
121     branch_target_t           *table;       /* for TABLESWITCH                */
122     lookup_target_t           *lookup;      /* for LOOKUPSWITCH               */
123     int32_t                    insindex;    /* used in parse                  */
124 } dst_operand_t;
125
126 /*** flags (32 bits) ***/
127
128 #define INS_FLAG_BASICBLOCK    0x01    /* marks a basic block start           */
129 #define INS_FLAG_UNRESOLVED    0x02    /* contains unresolved field/meth/class*/
130 #define INS_FLAG_CLASS         0x04    /* for ACONST, PUT*CONST with class    */
131 #define INS_FLAG_ARRAY         0x08    /* for CHECKCAST/INSTANCEOF with array */
132 #define INS_FLAG_CHECK         0x10    /* for *ALOAD|*ASTORE: check index     */
133                                        /* for BUILTIN: check exception        */
134 #define INS_FLAG_KILL_PREV     0x04    /* for *STORE, invalidate prev local   */
135 #define INS_FLAG_KILL_NEXT     0x08    /* for *STORE, invalidate next local   */
136 #define INS_FLAG_RETADDR       0x10    /* for ASTORE: op is a returnAddress   */
137
138 #define INS_FLAG_ID_SHIFT      5
139 #define INS_FLAG_ID_MASK       (~0 << INS_FLAG_ID_SHIFT)
140
141 typedef union {
142     u4                  bits;
143 } flags_operand_t;
144
145
146 // Instruction.
147
148 /* The instruction format for the intermediate representation: */
149
150 struct instruction {
151     u2                      opc;    /* opcode       */
152     u2                      line;   /* line number  */
153 #if SIZEOF_VOID_P == 8
154     flags_operand_t         flags;  /* 4 bytes      */
155 #endif
156     s1_operand_t            s1;     /* pointer-size */
157     union {
158         struct {
159             s2_operand_t    s2;     /* pointer-size */
160             s3_operand_t    s3;     /* pointer-size */
161         } s23;                      /*     XOR      */
162         val_operand_t       val;    /*  long-size   */
163     } sx;
164     dst_operand_t           dst;    /* pointer-size */
165 #if SIZEOF_VOID_P == 4
166     flags_operand_t         flags;  /* 4 bytes      */
167 #endif
168 #if defined(ENABLE_ESCAPE_REASON)
169         void *escape_reasons;
170 #endif
171 };
172
173
174 #define INSTRUCTION_STARTS_BASICBLOCK(iptr) \
175         ((iptr)->flags.bits & INS_FLAG_BASICBLOCK)
176
177 #define INSTRUCTION_IS_RESOLVED(iptr) \
178         (!((iptr)->flags.bits & INS_FLAG_UNRESOLVED))
179
180 #define INSTRUCTION_IS_UNRESOLVED(iptr) \
181         ((iptr)->flags.bits & INS_FLAG_UNRESOLVED)
182
183 #define INSTRUCTION_MUST_CHECK(iptr) \
184         ((iptr)->flags.bits & INS_FLAG_CHECK)
185
186 #define INSTRUCTION_GET_FIELDREF(iptr,fref) \
187         do { \
188                 if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
189                         fref = iptr->sx.s23.s3.uf->fieldref; \
190                 else \
191                         fref = iptr->sx.s23.s3.fmiref; \
192         } while (0)
193
194 #define INSTRUCTION_GET_METHODREF(iptr,mref) \
195         do { \
196                 if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
197                         mref = iptr->sx.s23.s3.um->methodref; \
198                 else \
199                         mref = iptr->sx.s23.s3.fmiref; \
200         } while (0)
201
202 #define INSTRUCTION_GET_METHODDESC(iptr, md) \
203         do { \
204                 if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
205                         md = iptr->sx.s23.s3.um->methodref->parseddesc.md; \
206                 else \
207                         md = iptr->sx.s23.s3.fmiref->parseddesc.md; \
208         } while (0)
209
210
211 /* additional info structs for special instructions ***************************/
212
213 /* for ICMD_INLINE_START and ICMD_INLINE_END */
214
215 struct insinfo_inline {
216         /* fields copied from the inlining tree ----------------------------------*/
217         insinfo_inline *parent;     /* insinfo of the surrounding inlining, if any*/
218         methodinfo     *method;     /* the inlined method starting/ending here    */
219         methodinfo     *outer;      /* the outer method suspended/resumed here    */
220         int32_t         synclocal;      /* local index used for synchronization   */
221         bool            synchronize;    /* true if synchronization is needed      */
222         int32_t         throughcount;   /* total # of pass-through variables      */
223         int32_t         paramcount;     /* number of parameters of original call  */
224         int32_t         stackvarscount; /* source stackdepth at INLINE_START      */
225         int32_t        *stackvars;      /* stack vars at INLINE_START             */
226
227         /* fields set by inlining ------------------------------------------------*/
228         int32_t    *javalocals_start; /* javalocals at start of inlined body      */
229         int32_t    *javalocals_end;   /* javalocals after inlined body            */
230
231         /* fields set by replacement point creation ------------------------------*/
232 #if defined(ENABLE_REPLACEMENT)
233         rplpoint   *rp;             /* replacement point at INLINE_START          */
234 #endif
235
236         /* fields set by the codegen ---------------------------------------------*/
237         int32_t     startmpc;       /* machine code offset of start of inlining   */
238 };
239
240
241 /* Additional instruction accessors */
242
243 methoddesc* instruction_call_site(const instruction* iptr);
244
245 static inline bool instruction_has_dst(const instruction* iptr)
246 {
247         if (
248                 (icmd_table[iptr->opc].dataflow == DF_INVOKE) ||
249                 (icmd_table[iptr->opc].dataflow == DF_BUILTIN)
250                 ) {
251                 return instruction_call_site(iptr)->returntype.type != TYPE_VOID;
252         }
253         else {
254                 return icmd_table[iptr->opc].dataflow >= DF_DST_BASE;
255         }
256 }
257
258 #ifdef __cplusplus
259 }
260 #endif
261
262 #endif // _INSTRUCTION_HPP
263
264
265 /*
266  * These are local overrides for various environment variables in Emacs.
267  * Please do not remove this and leave it at the end of the file, where
268  * Emacs will automagically detect them.
269  * ---------------------------------------------------------------------
270  * Local variables:
271  * mode: c++
272  * indent-tabs-mode: t
273  * c-basic-offset: 4
274  * tab-width: 4
275  * End:
276  * vim:noexpandtab:sw=4:ts=4:
277  */