]> git.proxmox.com Git - qemu.git/blame - tcg/tcg.h
Robustify source directory check.
[qemu.git] / tcg / tcg.h
CommitLineData
c896fe29
FB
1/*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include "tcg-target.h"
25
26#if TCG_TARGET_REG_BITS == 32
27typedef int32_t tcg_target_long;
28typedef uint32_t tcg_target_ulong;
29#define TCG_PRIlx PRIx32
30#define TCG_PRIld PRId32
31#elif TCG_TARGET_REG_BITS == 64
32typedef int64_t tcg_target_long;
33typedef uint64_t tcg_target_ulong;
34#define TCG_PRIlx PRIx64
35#define TCG_PRIld PRId64
36#else
37#error unsupported
38#endif
39
40#if TCG_TARGET_NB_REGS <= 32
41typedef uint32_t TCGRegSet;
42#elif TCG_TARGET_NB_REGS <= 64
43typedef uint64_t TCGRegSet;
44#else
45#error unsupported
46#endif
47
48enum {
49#define DEF(s, n, copy_size) INDEX_op_ ## s,
50#include "tcg-opc.h"
51#undef DEF
52 NB_OPS,
53};
54
55#define tcg_regset_clear(d) (d) = 0
56#define tcg_regset_set(d, s) (d) = (s)
57#define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg)
58#define tcg_regset_set_reg(d, r) (d) |= 1 << (r)
59#define tcg_regset_reset_reg(d, r) (d) &= ~(1 << (r))
60#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
61#define tcg_regset_or(d, a, b) (d) = (a) | (b)
62#define tcg_regset_and(d, a, b) (d) = (a) & (b)
63#define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b)
64#define tcg_regset_not(d, a) (d) = ~(a)
65
66typedef struct TCGRelocation {
67 struct TCGRelocation *next;
68 int type;
69 uint8_t *ptr;
70 tcg_target_long addend;
71} TCGRelocation;
72
73typedef struct TCGLabel {
74 int has_value;
75 union {
76 tcg_target_ulong value;
77 TCGRelocation *first_reloc;
78 } u;
79} TCGLabel;
80
81typedef struct TCGPool {
82 struct TCGPool *next;
83 int size;
84 uint8_t data[0];
85} TCGPool;
86
87#define TCG_POOL_CHUNK_SIZE 32768
88
89#define TCG_MAX_LABELS 512
90
91#define TCG_MAX_TEMPS 256
92
93typedef int TCGType;
94
95#define TCG_TYPE_I32 0
96#define TCG_TYPE_I64 1
97
98#if TCG_TARGET_REG_BITS == 32
99#define TCG_TYPE_PTR TCG_TYPE_I32
100#else
101#define TCG_TYPE_PTR TCG_TYPE_I64
102#endif
103
104typedef tcg_target_ulong TCGArg;
105
106/* call flags */
107#define TCG_CALL_TYPE_MASK 0x000f
108#define TCG_CALL_TYPE_STD 0x0000 /* standard C call */
109#define TCG_CALL_TYPE_REGPARM_1 0x0001 /* i386 style regparm call (1 reg) */
110#define TCG_CALL_TYPE_REGPARM_2 0x0002 /* i386 style regparm call (2 regs) */
111#define TCG_CALL_TYPE_REGPARM 0x0003 /* i386 style regparm call (3 regs) */
112
113typedef enum {
114 TCG_COND_EQ,
115 TCG_COND_NE,
116 TCG_COND_LT,
117 TCG_COND_GE,
118 TCG_COND_LE,
119 TCG_COND_GT,
120 /* unsigned */
121 TCG_COND_LTU,
122 TCG_COND_GEU,
123 TCG_COND_LEU,
124 TCG_COND_GTU,
125} TCGCond;
126
127#define TEMP_VAL_DEAD 0
128#define TEMP_VAL_REG 1
129#define TEMP_VAL_MEM 2
130#define TEMP_VAL_CONST 3
131
132/* XXX: optimize memory layout */
133typedef struct TCGTemp {
134 TCGType base_type;
135 TCGType type;
136 int val_type;
137 int reg;
138 tcg_target_long val;
139 int mem_reg;
140 tcg_target_long mem_offset;
141 unsigned int fixed_reg:1;
142 unsigned int mem_coherent:1;
143 unsigned int mem_allocated:1;
144 const char *name;
145} TCGTemp;
146
147typedef struct TCGHelperInfo {
148 void *func;
149 const char *name;
150} TCGHelperInfo;
151
152typedef struct TCGContext TCGContext;
153
154typedef void TCGMacroFunc(TCGContext *s, int macro_id, const int *dead_args);
155
156struct TCGContext {
157 uint8_t *pool_cur, *pool_end;
158 TCGPool *pool_first, *pool_current;
159 TCGLabel *labels;
160 int nb_labels;
161 TCGTemp *temps; /* globals first, temps after */
162 int nb_globals;
163 int nb_temps;
164 /* constant indexes (end of temp array) */
165 int const_start;
166 int const_end;
167
168 /* goto_tb support */
169 uint8_t *code_buf;
170 unsigned long *tb_next;
171 uint16_t *tb_next_offset;
172 uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
173
174 uint16_t *op_dead_iargs; /* for each operation, each bit tells if the
175 corresponding input argument is dead */
176 /* tells in which temporary a given register is. It does not take
177 into account fixed registers */
178 int reg_to_temp[TCG_TARGET_NB_REGS];
179 TCGRegSet reserved_regs;
180 tcg_target_long current_frame_offset;
181 tcg_target_long frame_start;
182 tcg_target_long frame_end;
183 int frame_reg;
184
185 uint8_t *code_ptr;
186 TCGTemp static_temps[TCG_MAX_TEMPS];
187
188 TCGMacroFunc *macro_func;
189 TCGHelperInfo *helpers;
190 int nb_helpers;
191 int allocated_helpers;
192};
193
194extern TCGContext tcg_ctx;
195extern uint16_t *gen_opc_ptr;
196extern TCGArg *gen_opparam_ptr;
197extern uint16_t gen_opc_buf[];
198extern TCGArg gen_opparam_buf[];
199
200/* pool based memory allocation */
201
202void *tcg_malloc_internal(TCGContext *s, int size);
203void tcg_pool_reset(TCGContext *s);
204void tcg_pool_delete(TCGContext *s);
205
206static inline void *tcg_malloc(int size)
207{
208 TCGContext *s = &tcg_ctx;
209 uint8_t *ptr, *ptr_end;
210 size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
211 ptr = s->pool_cur;
212 ptr_end = ptr + size;
213 if (unlikely(ptr_end > s->pool_end)) {
214 return tcg_malloc_internal(&tcg_ctx, size);
215 } else {
216 s->pool_cur = ptr_end;
217 return ptr;
218 }
219}
220
221void tcg_context_init(TCGContext *s);
222void tcg_func_start(TCGContext *s);
223
224int dyngen_code(TCGContext *s, uint8_t *gen_code_buf);
225int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf,
226 const uint8_t *searched_pc);
227
228void tcg_set_frame(TCGContext *s, int reg,
229 tcg_target_long start, tcg_target_long size);
230void tcg_set_macro_func(TCGContext *s, TCGMacroFunc *func);
231int tcg_global_reg_new(TCGType type, int reg, const char *name);
232int tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
233 const char *name);
234int tcg_temp_new(TCGType type);
235char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGArg arg);
236
237#define TCG_CT_ALIAS 0x80
238#define TCG_CT_IALIAS 0x40
239#define TCG_CT_REG 0x01
240#define TCG_CT_CONST 0x02 /* any constant of register size */
241
242typedef struct TCGArgConstraint {
243 uint32_t ct;
244 union {
245 TCGRegSet regs;
246 } u;
247} TCGArgConstraint;
248
249#define TCG_MAX_OP_ARGS 16
250
251#define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic
252 block */
253#define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers */
254
255typedef struct TCGOpDef {
256 const char *name;
257 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
258 uint8_t flags;
259 uint16_t copy_size;
260 TCGArgConstraint *args_ct;
261 int *sorted_args;
262} TCGOpDef;
263
264typedef struct TCGTargetOpDef {
265 int op;
266 const char *args_ct_str[TCG_MAX_OP_ARGS];
267} TCGTargetOpDef;
268
269extern TCGOpDef tcg_op_defs[];
270
271void tcg_target_init(TCGContext *s);
272
273#define tcg_abort() \
274do {\
275 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
276 abort();\
277} while (0)
278
279void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
280
281void tcg_gen_call(TCGContext *s, TCGArg func, unsigned int flags,
282 unsigned int nb_rets, const TCGArg *rets,
283 unsigned int nb_params, const TCGArg *args1);
284void tcg_gen_shifti_i64(TCGArg ret, TCGArg arg1,
285 int c, int right, int arith);
286
287/* only used for debugging purposes */
288void tcg_register_helper(void *func, const char *name);
289#define TCG_HELPER(func) tcg_register_helper(func, #func)
290const char *tcg_helper_get_name(TCGContext *s, void *func);
291void tcg_dump_ops(TCGContext *s, FILE *outfile);
292
293void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
294int tcg_const_i32(int32_t val);
295int tcg_const_i64(int64_t val);
296
297#if TCG_TARGET_REG_BITS == 32
298#define tcg_const_ptr tcg_const_i32
299#define tcg_add_ptr tcg_add_i32
300#define tcg_sub_ptr tcg_sub_i32
301#else
302#define tcg_const_ptr tcg_const_i64
303#define tcg_add_ptr tcg_add_i64
304#define tcg_sub_ptr tcg_sub_i64
305#endif
306
307void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
308 int label_index, long addend);
309void tcg_reg_alloc_start(TCGContext *s);
310void tcg_reg_alloc_bb_end(TCGContext *s);
311void tcg_liveness_analysis(TCGContext *s);
312const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
313 unsigned int dead_iargs);
314
315const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr);
316
317/* tcg-runtime.c */
318int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2);
319int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2);
320int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2);
321int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2);
322int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2);
323uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2);
324uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2);