Statistics
| Branch: | Revision:

root / tcg / tcg.h @ c896fe29

History | View | Annotate | Download (9.3 kB)

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
27
typedef int32_t tcg_target_long;
28
typedef uint32_t tcg_target_ulong;
29
#define TCG_PRIlx PRIx32
30
#define TCG_PRIld PRId32
31
#elif TCG_TARGET_REG_BITS == 64
32
typedef int64_t tcg_target_long;
33
typedef 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
41
typedef uint32_t TCGRegSet;
42
#elif TCG_TARGET_NB_REGS <= 64
43
typedef uint64_t TCGRegSet;
44
#else
45
#error unsupported
46
#endif
47

    
48
enum {
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

    
66
typedef struct TCGRelocation {
67
    struct TCGRelocation *next;
68
    int type;
69
    uint8_t *ptr;
70
    tcg_target_long addend;
71
} TCGRelocation; 
72

    
73
typedef struct TCGLabel {
74
    int has_value;
75
    union {
76
        tcg_target_ulong value;
77
        TCGRelocation *first_reloc;
78
    } u;
79
} TCGLabel;
80

    
81
typedef 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

    
93
typedef 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

    
104
typedef 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

    
113
typedef 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 */
133
typedef 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

    
147
typedef struct TCGHelperInfo {
148
    void *func;
149
    const char *name;
150
} TCGHelperInfo;
151

    
152
typedef struct TCGContext TCGContext;
153

    
154
typedef void TCGMacroFunc(TCGContext *s, int macro_id, const int *dead_args);
155

    
156
struct 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

    
194
extern TCGContext tcg_ctx;
195
extern uint16_t *gen_opc_ptr;
196
extern TCGArg *gen_opparam_ptr;
197
extern uint16_t gen_opc_buf[];
198
extern TCGArg gen_opparam_buf[];
199

    
200
/* pool based memory allocation */
201

    
202
void *tcg_malloc_internal(TCGContext *s, int size);
203
void tcg_pool_reset(TCGContext *s);
204
void tcg_pool_delete(TCGContext *s);
205

    
206
static 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

    
221
void tcg_context_init(TCGContext *s);
222
void tcg_func_start(TCGContext *s);
223

    
224
int dyngen_code(TCGContext *s, uint8_t *gen_code_buf);
225
int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf,
226
                          const uint8_t *searched_pc);
227

    
228
void tcg_set_frame(TCGContext *s, int reg,
229
                   tcg_target_long start, tcg_target_long size);
230
void tcg_set_macro_func(TCGContext *s, TCGMacroFunc *func);
231
int tcg_global_reg_new(TCGType type, int reg, const char *name);
232
int tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
233
                       const char *name);
234
int tcg_temp_new(TCGType type);
235
char *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

    
242
typedef 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

    
255
typedef 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
        
264
typedef struct TCGTargetOpDef {
265
    int op;
266
    const char *args_ct_str[TCG_MAX_OP_ARGS];
267
} TCGTargetOpDef;
268

    
269
extern TCGOpDef tcg_op_defs[];
270

    
271
void tcg_target_init(TCGContext *s);
272

    
273
#define tcg_abort() \
274
do {\
275
    fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
276
    abort();\
277
} while (0)
278

    
279
void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
280

    
281
void 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);
284
void tcg_gen_shifti_i64(TCGArg ret, TCGArg arg1, 
285
                        int c, int right, int arith);
286

    
287
/* only used for debugging purposes */
288
void tcg_register_helper(void *func, const char *name);
289
#define TCG_HELPER(func) tcg_register_helper(func, #func)
290
const char *tcg_helper_get_name(TCGContext *s, void *func);
291
void tcg_dump_ops(TCGContext *s, FILE *outfile);
292

    
293
void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
294
int tcg_const_i32(int32_t val);
295
int 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

    
307
void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, 
308
                   int label_index, long addend);
309
void tcg_reg_alloc_start(TCGContext *s);
310
void tcg_reg_alloc_bb_end(TCGContext *s);
311
void tcg_liveness_analysis(TCGContext *s);
312
const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
313
                              unsigned int dead_iargs);
314

    
315
const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr);
316

    
317
/* tcg-runtime.c */
318
int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2);
319
int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2);
320
int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2);
321
int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2);
322
int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2);
323
uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2);
324
uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2);