|
|
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.
1.1.1.6 ! root 132: In addition we do typechecking for different types of variables. TCGv_i32
1.1 root 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:
1.1.1.6 ! root 153: typedef struct {
! 154: int iptr;
! 155: } TCGv_ptr;
! 156:
1.1 root 157: #define MAKE_TCGV_I32(i) __extension__ \
158: ({ TCGv_i32 make_tcgv_tmp = {i}; make_tcgv_tmp;})
159: #define MAKE_TCGV_I64(i) __extension__ \
160: ({ TCGv_i64 make_tcgv_tmp = {i}; make_tcgv_tmp;})
1.1.1.6 ! root 161: #define MAKE_TCGV_PTR(i) __extension__ \
! 162: ({ TCGv_ptr make_tcgv_tmp = {i}; make_tcgv_tmp; })
1.1 root 163: #define GET_TCGV_I32(t) ((t).i32)
164: #define GET_TCGV_I64(t) ((t).i64)
1.1.1.6 ! root 165: #define GET_TCGV_PTR(t) ((t).iptr)
1.1 root 166: #if TCG_TARGET_REG_BITS == 32
167: #define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
168: #define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
169: #endif
170:
171: #else /* !DEBUG_TCGV */
172:
173: typedef int TCGv_i32;
174: typedef int TCGv_i64;
1.1.1.6 ! root 175: #if TCG_TARGET_REG_BITS == 32
! 176: #define TCGv_ptr TCGv_i32
! 177: #else
! 178: #define TCGv_ptr TCGv_i64
! 179: #endif
1.1 root 180: #define MAKE_TCGV_I32(x) (x)
181: #define MAKE_TCGV_I64(x) (x)
1.1.1.6 ! root 182: #define MAKE_TCGV_PTR(x) (x)
1.1 root 183: #define GET_TCGV_I32(t) (t)
184: #define GET_TCGV_I64(t) (t)
1.1.1.6 ! root 185: #define GET_TCGV_PTR(t) (t)
1.1.1.2 root 186:
1.1 root 187: #if TCG_TARGET_REG_BITS == 32
188: #define TCGV_LOW(t) (t)
189: #define TCGV_HIGH(t) ((t) + 1)
190: #endif
191:
192: #endif /* DEBUG_TCGV */
193:
1.1.1.2 root 194: #define TCGV_EQUAL_I32(a, b) (GET_TCGV_I32(a) == GET_TCGV_I32(b))
195: #define TCGV_EQUAL_I64(a, b) (GET_TCGV_I64(a) == GET_TCGV_I64(b))
196:
1.1 root 197: /* Dummy definition to avoid compiler warnings. */
198: #define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1)
199: #define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1)
200:
201: /* call flags */
202: #define TCG_CALL_TYPE_MASK 0x000f
203: #define TCG_CALL_TYPE_STD 0x0000 /* standard C call */
204: #define TCG_CALL_TYPE_REGPARM_1 0x0001 /* i386 style regparm call (1 reg) */
205: #define TCG_CALL_TYPE_REGPARM_2 0x0002 /* i386 style regparm call (2 regs) */
206: #define TCG_CALL_TYPE_REGPARM 0x0003 /* i386 style regparm call (3 regs) */
1.1.1.2 root 207: /* A pure function only reads its arguments and TCG global variables
208: and cannot raise exceptions. Hence a call to a pure function can be
1.1 root 209: safely suppressed if the return value is not used. */
210: #define TCG_CALL_PURE 0x0010
1.1.1.2 root 211: /* A const function only reads its arguments and does not use TCG
212: global variables. Hence a call to such a function does not
213: save TCG global variables back to their canonical location. */
214: #define TCG_CALL_CONST 0x0020
1.1 root 215:
216: /* used to align parameters */
217: #define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1)
218: #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1))
219:
220: typedef enum {
221: TCG_COND_EQ,
222: TCG_COND_NE,
223: TCG_COND_LT,
224: TCG_COND_GE,
225: TCG_COND_LE,
226: TCG_COND_GT,
227: /* unsigned */
228: TCG_COND_LTU,
229: TCG_COND_GEU,
230: TCG_COND_LEU,
231: TCG_COND_GTU,
232: } TCGCond;
233:
1.1.1.4 root 234: /* Invert the sense of the comparison. */
235: static inline TCGCond tcg_invert_cond(TCGCond c)
236: {
237: return (TCGCond)(c ^ 1);
238: }
239:
240: /* Swap the operands in a comparison. */
241: static inline TCGCond tcg_swap_cond(TCGCond c)
242: {
243: int mask = (c < TCG_COND_LT ? 0 : c < TCG_COND_LTU ? 7 : 15);
244: return (TCGCond)(c ^ mask);
245: }
246:
247: static inline TCGCond tcg_unsigned_cond(TCGCond c)
248: {
249: return (c >= TCG_COND_LT && c <= TCG_COND_GT ? c + 4 : c);
250: }
251:
1.1 root 252: #define TEMP_VAL_DEAD 0
253: #define TEMP_VAL_REG 1
254: #define TEMP_VAL_MEM 2
255: #define TEMP_VAL_CONST 3
256:
257: /* XXX: optimize memory layout */
258: typedef struct TCGTemp {
259: TCGType base_type;
260: TCGType type;
261: int val_type;
262: int reg;
263: tcg_target_long val;
264: int mem_reg;
265: tcg_target_long mem_offset;
266: unsigned int fixed_reg:1;
267: unsigned int mem_coherent:1;
268: unsigned int mem_allocated:1;
1.1.1.6 ! root 269: unsigned int temp_local:1; /* If true, the temp is saved across
1.1 root 270: basic blocks. Otherwise, it is not
1.1.1.6 ! root 271: preserved across basic blocks. */
1.1 root 272: unsigned int temp_allocated:1; /* never used for code gen */
273: /* index of next free temp of same base type, -1 if end */
274: int next_free_temp;
275: const char *name;
276: } TCGTemp;
277:
278: typedef struct TCGHelperInfo {
279: tcg_target_ulong func;
280: const char *name;
281: } TCGHelperInfo;
282:
283: typedef struct TCGContext TCGContext;
284:
285: struct TCGContext {
286: uint8_t *pool_cur, *pool_end;
287: TCGPool *pool_first, *pool_current;
288: TCGLabel *labels;
289: int nb_labels;
290: TCGTemp *temps; /* globals first, temps after */
291: int nb_globals;
292: int nb_temps;
293: /* index of free temps, -1 if none */
294: int first_free_temp[TCG_TYPE_COUNT * 2];
295:
296: /* goto_tb support */
297: uint8_t *code_buf;
298: unsigned long *tb_next;
299: uint16_t *tb_next_offset;
300: uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
301:
302: /* liveness analysis */
1.1.1.6 ! root 303: uint16_t *op_dead_args; /* for each operation, each bit tells if the
! 304: corresponding argument is dead */
1.1 root 305:
306: /* tells in which temporary a given register is. It does not take
307: into account fixed registers */
308: int reg_to_temp[TCG_TARGET_NB_REGS];
309: TCGRegSet reserved_regs;
310: tcg_target_long current_frame_offset;
311: tcg_target_long frame_start;
312: tcg_target_long frame_end;
313: int frame_reg;
314:
315: uint8_t *code_ptr;
316: TCGTemp static_temps[TCG_MAX_TEMPS];
317:
318: TCGHelperInfo *helpers;
319: int nb_helpers;
320: int allocated_helpers;
321: int helpers_sorted;
322:
323: #ifdef CONFIG_PROFILER
324: /* profiling info */
325: int64_t tb_count1;
326: int64_t tb_count;
327: int64_t op_count; /* total insn count */
328: int op_count_max; /* max insn per TB */
329: int64_t temp_count;
330: int temp_count_max;
331: int64_t del_op_count;
332: int64_t code_in_len;
333: int64_t code_out_len;
334: int64_t interm_time;
335: int64_t code_time;
336: int64_t la_time;
337: int64_t restore_count;
338: int64_t restore_time;
339: #endif
1.1.1.6 ! root 340:
! 341: #ifdef CONFIG_DEBUG_TCG
! 342: int temps_in_use;
! 343: #endif
1.1 root 344: };
345:
346: extern TCGContext tcg_ctx;
347: extern uint16_t *gen_opc_ptr;
348: extern TCGArg *gen_opparam_ptr;
349: extern uint16_t gen_opc_buf[];
350: extern TCGArg gen_opparam_buf[];
351:
352: /* pool based memory allocation */
353:
354: void *tcg_malloc_internal(TCGContext *s, int size);
355: void tcg_pool_reset(TCGContext *s);
356: void tcg_pool_delete(TCGContext *s);
357:
358: static inline void *tcg_malloc(int size)
359: {
360: TCGContext *s = &tcg_ctx;
361: uint8_t *ptr, *ptr_end;
362: size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
363: ptr = s->pool_cur;
364: ptr_end = ptr + size;
365: if (unlikely(ptr_end > s->pool_end)) {
366: return tcg_malloc_internal(&tcg_ctx, size);
367: } else {
368: s->pool_cur = ptr_end;
369: return ptr;
370: }
371: }
372:
373: void tcg_context_init(TCGContext *s);
1.1.1.4 root 374: void tcg_prologue_init(TCGContext *s);
1.1 root 375: void tcg_func_start(TCGContext *s);
376:
377: int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
378: int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
379:
380: void tcg_set_frame(TCGContext *s, int reg,
381: tcg_target_long start, tcg_target_long size);
382:
383: TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
384: TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
385: const char *name);
386: TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
387: static inline TCGv_i32 tcg_temp_new_i32(void)
388: {
389: return tcg_temp_new_internal_i32(0);
390: }
391: static inline TCGv_i32 tcg_temp_local_new_i32(void)
392: {
393: return tcg_temp_new_internal_i32(1);
394: }
395: void tcg_temp_free_i32(TCGv_i32 arg);
396: char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg);
397:
398: TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
399: TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
400: const char *name);
401: TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
402: static inline TCGv_i64 tcg_temp_new_i64(void)
403: {
404: return tcg_temp_new_internal_i64(0);
405: }
406: static inline TCGv_i64 tcg_temp_local_new_i64(void)
407: {
408: return tcg_temp_new_internal_i64(1);
409: }
410: void tcg_temp_free_i64(TCGv_i64 arg);
411: char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
412:
1.1.1.6 ! root 413: #if defined(CONFIG_DEBUG_TCG)
! 414: /* If you call tcg_clear_temp_count() at the start of a section of
! 415: * code which is not supposed to leak any TCG temporaries, then
! 416: * calling tcg_check_temp_count() at the end of the section will
! 417: * return 1 if the section did in fact leak a temporary.
! 418: */
! 419: void tcg_clear_temp_count(void);
! 420: int tcg_check_temp_count(void);
! 421: #else
! 422: #define tcg_clear_temp_count() do { } while (0)
! 423: #define tcg_check_temp_count() 0
! 424: #endif
! 425:
1.1.1.5 root 426: void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
1.1 root 427:
428: #define TCG_CT_ALIAS 0x80
429: #define TCG_CT_IALIAS 0x40
430: #define TCG_CT_REG 0x01
431: #define TCG_CT_CONST 0x02 /* any constant of register size */
432:
433: typedef struct TCGArgConstraint {
434: uint16_t ct;
435: uint8_t alias_index;
436: union {
437: TCGRegSet regs;
438: } u;
439: } TCGArgConstraint;
440:
441: #define TCG_MAX_OP_ARGS 16
442:
443: #define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic
444: block */
445: #define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers
446: and potentially update globals. */
447: #define TCG_OPF_SIDE_EFFECTS 0x04 /* instruction has side effects : it
448: cannot be removed if its output
449: are not used */
450:
451: typedef struct TCGOpDef {
452: const char *name;
453: uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
454: uint8_t flags;
455: TCGArgConstraint *args_ct;
456: int *sorted_args;
1.1.1.4 root 457: #if defined(CONFIG_DEBUG_TCG)
458: int used;
459: #endif
1.1 root 460: } TCGOpDef;
461:
462: typedef struct TCGTargetOpDef {
1.1.1.4 root 463: TCGOpcode op;
1.1 root 464: const char *args_ct_str[TCG_MAX_OP_ARGS];
465: } TCGTargetOpDef;
466:
467: #define tcg_abort() \
468: do {\
469: fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
470: abort();\
471: } while (0)
472:
473: void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
474:
475: #if TCG_TARGET_REG_BITS == 32
1.1.1.6 ! root 476: #define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n))
! 477: #define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n))
! 478:
! 479: #define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32(V))
! 480: #define tcg_global_reg_new_ptr(R, N) \
! 481: TCGV_NAT_TO_PTR(tcg_global_reg_new_i32((R), (N)))
! 482: #define tcg_global_mem_new_ptr(R, O, N) \
! 483: TCGV_NAT_TO_PTR(tcg_global_mem_new_i32((R), (O), (N)))
! 484: #define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i32())
! 485: #define tcg_temp_free_ptr(T) tcg_temp_free_i32(TCGV_PTR_TO_NAT(T))
1.1 root 486: #else
1.1.1.6 ! root 487: #define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I64(n))
! 488: #define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I64(GET_TCGV_PTR(n))
! 489:
! 490: #define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64(V))
! 491: #define tcg_global_reg_new_ptr(R, N) \
! 492: TCGV_NAT_TO_PTR(tcg_global_reg_new_i64((R), (N)))
! 493: #define tcg_global_mem_new_ptr(R, O, N) \
! 494: TCGV_NAT_TO_PTR(tcg_global_mem_new_i64((R), (O), (N)))
! 495: #define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i64())
! 496: #define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T))
1.1 root 497: #endif
498:
499: void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
500: int sizemask, TCGArg ret, int nargs, TCGArg *args);
501:
502: void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
503: int c, int right, int arith);
504:
505: /* only used for debugging purposes */
506: void tcg_register_helper(void *func, const char *name);
507: const char *tcg_helper_get_name(TCGContext *s, void *func);
508: void tcg_dump_ops(TCGContext *s, FILE *outfile);
509:
510: void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
511: TCGv_i32 tcg_const_i32(int32_t val);
512: TCGv_i64 tcg_const_i64(int64_t val);
513: TCGv_i32 tcg_const_local_i32(int32_t val);
514: TCGv_i64 tcg_const_local_i64(int64_t val);
515:
516: extern uint8_t code_gen_prologue[];
517: #if defined(_ARCH_PPC) && !defined(_ARCH_PPC64)
1.1.1.6 ! root 518: #define tcg_qemu_tb_exec(env, tb_ptr) \
! 519: ((long REGPARM __attribute__ ((longcall)) (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
1.1 root 520: #else
1.1.1.6 ! root 521: #define tcg_qemu_tb_exec(env, tb_ptr) \
! 522: ((long REGPARM (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
1.1 root 523: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.