|
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] __attribute__ ((aligned)); |
|
85 } TCGPool; |
|
86 |
|
87 #define TCG_POOL_CHUNK_SIZE 32768 |
|
88 |
|
89 #define TCG_MAX_LABELS 512 |
|
90 |
|
91 #define TCG_MAX_TEMPS 512 |
|
92 |
|
93 /* when the size of the arguments of a called function is smaller than |
|
94 this value, they are statically allocated in the TB stack frame */ |
|
95 #define TCG_STATIC_CALL_ARGS_SIZE 128 |
|
96 |
|
97 typedef int TCGType; |
|
98 |
|
99 #define TCG_TYPE_I32 0 |
|
100 #define TCG_TYPE_I64 1 |
|
101 #define TCG_TYPE_COUNT 2 /* number of different types */ |
|
102 |
|
103 #if TCG_TARGET_REG_BITS == 32 |
|
104 #define TCG_TYPE_PTR TCG_TYPE_I32 |
|
105 #else |
|
106 #define TCG_TYPE_PTR TCG_TYPE_I64 |
|
107 #endif |
|
108 |
|
109 typedef tcg_target_ulong TCGArg; |
|
110 |
|
111 /* Define a type and accessor macros for varables. Using a struct is |
|
112 nice because it gives some level of type safely. Ideally the compiler |
|
113 be able to see through all this. However in practice this is not true, |
|
114 expecially on targets with braindamaged ABIs (e.g. i386). |
|
115 We use plain int by default to avoid this runtime overhead. |
|
116 Users of tcg_gen_* don't need to know about any of this, and should |
|
117 treat TCGv as an opaque type. |
|
118 In additon we do typechecking for different types of variables. TCGv_i32 |
|
119 and TCGv_i64 are 32/64-bit variables respectively. TCGv and TCGv_ptr |
|
120 are aliases for target_ulong and host pointer sized values respectively. |
|
121 */ |
|
122 |
|
123 //#define DEBUG_TCGV 1 |
|
124 |
|
125 #ifdef DEBUG_TCGV |
|
126 |
|
127 typedef struct |
|
128 { |
|
129 int i32; |
|
130 } TCGv_i32; |
|
131 |
|
132 typedef struct |
|
133 { |
|
134 int i64; |
|
135 } TCGv_i64; |
|
136 |
|
137 #define MAKE_TCGV_I32(i) __extension__ \ |
|
138 ({ TCGv_i32 make_tcgv_tmp = {i}; make_tcgv_tmp;}) |
|
139 #define MAKE_TCGV_I64(i) __extension__ \ |
|
140 ({ TCGv_i64 make_tcgv_tmp = {i}; make_tcgv_tmp;}) |
|
141 #define GET_TCGV_I32(t) ((t).i32) |
|
142 #define GET_TCGV_I64(t) ((t).i64) |
|
143 #if TCG_TARGET_REG_BITS == 32 |
|
144 #define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t)) |
|
145 #define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1) |
|
146 #endif |
|
147 |
|
148 #else /* !DEBUG_TCGV */ |
|
149 |
|
150 typedef int TCGv_i32; |
|
151 typedef int TCGv_i64; |
|
152 #define MAKE_TCGV_I32(x) (x) |
|
153 #define MAKE_TCGV_I64(x) (x) |
|
154 #define GET_TCGV_I32(t) (t) |
|
155 #define GET_TCGV_I64(t) (t) |
|
156 #if TCG_TARGET_REG_BITS == 32 |
|
157 #define TCGV_LOW(t) (t) |
|
158 #define TCGV_HIGH(t) ((t) + 1) |
|
159 #endif |
|
160 |
|
161 #endif /* DEBUG_TCGV */ |
|
162 |
|
163 /* Dummy definition to avoid compiler warnings. */ |
|
164 #define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1) |
|
165 #define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1) |
|
166 |
|
167 /* call flags */ |
|
168 #define TCG_CALL_TYPE_MASK 0x000f |
|
169 #define TCG_CALL_TYPE_STD 0x0000 /* standard C call */ |
|
170 #define TCG_CALL_TYPE_REGPARM_1 0x0001 /* i386 style regparm call (1 reg) */ |
|
171 #define TCG_CALL_TYPE_REGPARM_2 0x0002 /* i386 style regparm call (2 regs) */ |
|
172 #define TCG_CALL_TYPE_REGPARM 0x0003 /* i386 style regparm call (3 regs) */ |
|
173 /* A pure function only reads its arguments and globals variables and |
|
174 cannot raise exceptions. Hence a call to a pure function can be |
|
175 safely suppressed if the return value is not used. */ |
|
176 #define TCG_CALL_PURE 0x0010 |
|
177 |
|
178 /* used to align parameters */ |
|
179 #define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1) |
|
180 #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1)) |
|
181 |
|
182 typedef enum { |
|
183 TCG_COND_EQ, |
|
184 TCG_COND_NE, |
|
185 TCG_COND_LT, |
|
186 TCG_COND_GE, |
|
187 TCG_COND_LE, |
|
188 TCG_COND_GT, |
|
189 /* unsigned */ |
|
190 TCG_COND_LTU, |
|
191 TCG_COND_GEU, |
|
192 TCG_COND_LEU, |
|
193 TCG_COND_GTU, |
|
194 } TCGCond; |
|
195 |
|
196 #define TEMP_VAL_DEAD 0 |
|
197 #define TEMP_VAL_REG 1 |
|
198 #define TEMP_VAL_MEM 2 |
|
199 #define TEMP_VAL_CONST 3 |
|
200 |
|
201 /* XXX: optimize memory layout */ |
|
202 typedef struct TCGTemp { |
|
203 TCGType base_type; |
|
204 TCGType type; |
|
205 int val_type; |
|
206 int reg; |
|
207 tcg_target_long val; |
|
208 int mem_reg; |
|
209 tcg_target_long mem_offset; |
|
210 unsigned int fixed_reg:1; |
|
211 unsigned int mem_coherent:1; |
|
212 unsigned int mem_allocated:1; |
|
213 unsigned int temp_local:1; /* If true, the temp is saved accross |
|
214 basic blocks. Otherwise, it is not |
|
215 preserved accross basic blocks. */ |
|
216 unsigned int temp_allocated:1; /* never used for code gen */ |
|
217 /* index of next free temp of same base type, -1 if end */ |
|
218 int next_free_temp; |
|
219 const char *name; |
|
220 } TCGTemp; |
|
221 |
|
222 typedef struct TCGHelperInfo { |
|
223 tcg_target_ulong func; |
|
224 const char *name; |
|
225 } TCGHelperInfo; |
|
226 |
|
227 typedef struct TCGContext TCGContext; |
|
228 |
|
229 struct TCGContext { |
|
230 uint8_t *pool_cur, *pool_end; |
|
231 TCGPool *pool_first, *pool_current; |
|
232 TCGLabel *labels; |
|
233 int nb_labels; |
|
234 TCGTemp *temps; /* globals first, temps after */ |
|
235 int nb_globals; |
|
236 int nb_temps; |
|
237 /* index of free temps, -1 if none */ |
|
238 int first_free_temp[TCG_TYPE_COUNT * 2]; |
|
239 |
|
240 /* goto_tb support */ |
|
241 uint8_t *code_buf; |
|
242 unsigned long *tb_next; |
|
243 uint16_t *tb_next_offset; |
|
244 uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */ |
|
245 |
|
246 /* liveness analysis */ |
|
247 uint16_t *op_dead_iargs; /* for each operation, each bit tells if the |
|
248 corresponding input argument is dead */ |
|
249 |
|
250 /* tells in which temporary a given register is. It does not take |
|
251 into account fixed registers */ |
|
252 int reg_to_temp[TCG_TARGET_NB_REGS]; |
|
253 TCGRegSet reserved_regs; |
|
254 tcg_target_long current_frame_offset; |
|
255 tcg_target_long frame_start; |
|
256 tcg_target_long frame_end; |
|
257 int frame_reg; |
|
258 |
|
259 uint8_t *code_ptr; |
|
260 TCGTemp static_temps[TCG_MAX_TEMPS]; |
|
261 |
|
262 TCGHelperInfo *helpers; |
|
263 int nb_helpers; |
|
264 int allocated_helpers; |
|
265 int helpers_sorted; |
|
266 |
|
267 #ifdef CONFIG_PROFILER |
|
268 /* profiling info */ |
|
269 int64_t tb_count1; |
|
270 int64_t tb_count; |
|
271 int64_t op_count; /* total insn count */ |
|
272 int op_count_max; /* max insn per TB */ |
|
273 int64_t temp_count; |
|
274 int temp_count_max; |
|
275 int64_t old_op_count; |
|
276 int64_t del_op_count; |
|
277 int64_t code_in_len; |
|
278 int64_t code_out_len; |
|
279 int64_t interm_time; |
|
280 int64_t code_time; |
|
281 int64_t la_time; |
|
282 int64_t restore_count; |
|
283 int64_t restore_time; |
|
284 #endif |
|
285 }; |
|
286 |
|
287 extern TCGContext tcg_ctx; |
|
288 extern uint16_t *gen_opc_ptr; |
|
289 extern TCGArg *gen_opparam_ptr; |
|
290 extern uint16_t gen_opc_buf[]; |
|
291 extern TCGArg gen_opparam_buf[]; |
|
292 |
|
293 /* pool based memory allocation */ |
|
294 |
|
295 void *tcg_malloc_internal(TCGContext *s, int size); |
|
296 void tcg_pool_reset(TCGContext *s); |
|
297 void tcg_pool_delete(TCGContext *s); |
|
298 |
|
299 static inline void *tcg_malloc(int size) |
|
300 { |
|
301 TCGContext *s = &tcg_ctx; |
|
302 uint8_t *ptr, *ptr_end; |
|
303 size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1); |
|
304 ptr = s->pool_cur; |
|
305 ptr_end = ptr + size; |
|
306 if (unlikely(ptr_end > s->pool_end)) { |
|
307 return tcg_malloc_internal(&tcg_ctx, size); |
|
308 } else { |
|
309 s->pool_cur = ptr_end; |
|
310 return ptr; |
|
311 } |
|
312 } |
|
313 |
|
314 void tcg_context_init(TCGContext *s); |
|
315 void tcg_func_start(TCGContext *s); |
|
316 |
|
317 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf); |
|
318 int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset); |
|
319 |
|
320 void tcg_set_frame(TCGContext *s, int reg, |
|
321 tcg_target_long start, tcg_target_long size); |
|
322 TCGv_i64 tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, |
|
323 const char *name); |
|
324 |
|
325 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name); |
|
326 TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset, |
|
327 const char *name); |
|
328 TCGv_i32 tcg_temp_new_internal_i32(int temp_local); |
|
329 static inline TCGv_i32 tcg_temp_new_i32(void) |
|
330 { |
|
331 return tcg_temp_new_internal_i32(0); |
|
332 } |
|
333 static inline TCGv_i32 tcg_temp_local_new_i32(void) |
|
334 { |
|
335 return tcg_temp_new_internal_i32(1); |
|
336 } |
|
337 void tcg_temp_free_i32(TCGv_i32 arg); |
|
338 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg); |
|
339 |
|
340 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name); |
|
341 TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset, |
|
342 const char *name); |
|
343 TCGv_i64 tcg_temp_new_internal_i64(int temp_local); |
|
344 static inline TCGv_i64 tcg_temp_new_i64(void) |
|
345 { |
|
346 return tcg_temp_new_internal_i64(0); |
|
347 } |
|
348 static inline TCGv_i64 tcg_temp_local_new_i64(void) |
|
349 { |
|
350 return tcg_temp_new_internal_i64(1); |
|
351 } |
|
352 void tcg_temp_free_i64(TCGv_i64 arg); |
|
353 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg); |
|
354 |
|
355 void tcg_dump_info(FILE *f, |
|
356 int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); |
|
357 |
|
358 #define TCG_CT_ALIAS 0x80 |
|
359 #define TCG_CT_IALIAS 0x40 |
|
360 #define TCG_CT_REG 0x01 |
|
361 #define TCG_CT_CONST 0x02 /* any constant of register size */ |
|
362 |
|
363 typedef struct TCGArgConstraint { |
|
364 uint16_t ct; |
|
365 uint8_t alias_index; |
|
366 union { |
|
367 TCGRegSet regs; |
|
368 } u; |
|
369 } TCGArgConstraint; |
|
370 |
|
371 #define TCG_MAX_OP_ARGS 16 |
|
372 |
|
373 #define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic |
|
374 block */ |
|
375 #define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers |
|
376 and potentially update globals. */ |
|
377 #define TCG_OPF_SIDE_EFFECTS 0x04 /* instruction has side effects : it |
|
378 cannot be removed if its output |
|
379 are not used */ |
|
380 |
|
381 typedef struct TCGOpDef { |
|
382 const char *name; |
|
383 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args; |
|
384 uint8_t flags; |
|
385 uint16_t copy_size; |
|
386 TCGArgConstraint *args_ct; |
|
387 int *sorted_args; |
|
388 } TCGOpDef; |
|
389 |
|
390 typedef struct TCGTargetOpDef { |
|
391 int op; |
|
392 const char *args_ct_str[TCG_MAX_OP_ARGS]; |
|
393 } TCGTargetOpDef; |
|
394 |
|
395 extern TCGOpDef tcg_op_defs[]; |
|
396 |
|
397 void tcg_target_init(TCGContext *s); |
|
398 void tcg_target_qemu_prologue(TCGContext *s); |
|
399 |
|
400 #define tcg_abort() \ |
|
401 do {\ |
|
402 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\ |
|
403 abort();\ |
|
404 } while (0) |
|
405 |
|
406 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs); |
|
407 |
|
408 #if TCG_TARGET_REG_BITS == 32 |
|
409 #define tcg_const_ptr tcg_const_i32 |
|
410 #define tcg_add_ptr tcg_add_i32 |
|
411 #define tcg_sub_ptr tcg_sub_i32 |
|
412 #define TCGv_ptr TCGv_i32 |
|
413 #define GET_TCGV_PTR GET_TCGV_I32 |
|
414 #define tcg_global_reg_new_ptr tcg_global_reg_new_i32 |
|
415 #define tcg_global_mem_new_ptr tcg_global_mem_new_i32 |
|
416 #define tcg_temp_new_ptr tcg_temp_new_i32 |
|
417 #define tcg_temp_free_ptr tcg_temp_free_i32 |
|
418 #else |
|
419 #define tcg_const_ptr tcg_const_i64 |
|
420 #define tcg_add_ptr tcg_add_i64 |
|
421 #define tcg_sub_ptr tcg_sub_i64 |
|
422 #define TCGv_ptr TCGv_i64 |
|
423 #define GET_TCGV_PTR GET_TCGV_I64 |
|
424 #define tcg_global_reg_new_ptr tcg_global_reg_new_i64 |
|
425 #define tcg_global_mem_new_ptr tcg_global_mem_new_i64 |
|
426 #define tcg_temp_new_ptr tcg_temp_new_i64 |
|
427 #define tcg_temp_free_ptr tcg_temp_free_i64 |
|
428 #endif |
|
429 |
|
430 void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, |
|
431 int sizemask, TCGArg ret, int nargs, TCGArg *args); |
|
432 |
|
433 void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, |
|
434 int c, int right, int arith); |
|
435 |
|
436 /* only used for debugging purposes */ |
|
437 void tcg_register_helper(void *func, const char *name); |
|
438 const char *tcg_helper_get_name(TCGContext *s, void *func); |
|
439 void tcg_dump_ops(TCGContext *s, FILE *outfile); |
|
440 |
|
441 void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf); |
|
442 TCGv_i32 tcg_const_i32(int32_t val); |
|
443 TCGv_i64 tcg_const_i64(int64_t val); |
|
444 TCGv_i32 tcg_const_local_i32(int32_t val); |
|
445 TCGv_i64 tcg_const_local_i64(int64_t val); |
|
446 |
|
447 void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, |
|
448 int label_index, long addend); |
|
449 const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1, |
|
450 unsigned int dead_iargs); |
|
451 |
|
452 /* tcg-runtime.c */ |
|
453 int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2); |
|
454 int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2); |
|
455 int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2); |
|
456 int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2); |
|
457 int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2); |
|
458 uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2); |
|
459 uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2); |
|
460 |
|
461 extern uint8_t code_gen_prologue[]; |
|
462 #if defined(__powerpc__) && !defined(__powerpc64__) |
|
463 #define tcg_qemu_tb_exec(tb_ptr) \ |
|
464 ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr) |
|
465 #else |
|
466 #define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr) |
|
467 #endif |