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