Statistics
| Branch: | Revision:

root / tcg / tcg.h @ 3d575329

History | View | Annotate | Download (9.3 kB)

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