|
|
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: */
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 del_op_count;
276: int64_t code_in_len;
277: int64_t code_out_len;
278: int64_t interm_time;
279: int64_t code_time;
280: int64_t la_time;
281: int64_t restore_count;
282: int64_t restore_time;
283: #endif
284: };
285:
286: extern TCGContext tcg_ctx;
287: extern uint16_t *gen_opc_ptr;
288: extern TCGArg *gen_opparam_ptr;
289: extern uint16_t gen_opc_buf[];
290: extern TCGArg gen_opparam_buf[];
291:
292: /* pool based memory allocation */
293:
294: void *tcg_malloc_internal(TCGContext *s, int size);
295: void tcg_pool_reset(TCGContext *s);
296: void tcg_pool_delete(TCGContext *s);
297:
298: static inline void *tcg_malloc(int size)
299: {
300: TCGContext *s = &tcg_ctx;
301: uint8_t *ptr, *ptr_end;
302: size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
303: ptr = s->pool_cur;
304: ptr_end = ptr + size;
305: if (unlikely(ptr_end > s->pool_end)) {
306: return tcg_malloc_internal(&tcg_ctx, size);
307: } else {
308: s->pool_cur = ptr_end;
309: return ptr;
310: }
311: }
312:
313: void tcg_context_init(TCGContext *s);
314: void tcg_func_start(TCGContext *s);
315:
316: int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
317: int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
318:
319: void tcg_set_frame(TCGContext *s, int reg,
320: tcg_target_long start, tcg_target_long size);
321:
322: TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
323: TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
324: const char *name);
325: TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
326: static inline TCGv_i32 tcg_temp_new_i32(void)
327: {
328: return tcg_temp_new_internal_i32(0);
329: }
330: static inline TCGv_i32 tcg_temp_local_new_i32(void)
331: {
332: return tcg_temp_new_internal_i32(1);
333: }
334: void tcg_temp_free_i32(TCGv_i32 arg);
335: char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg);
336:
337: TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
338: TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
339: const char *name);
340: TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
341: static inline TCGv_i64 tcg_temp_new_i64(void)
342: {
343: return tcg_temp_new_internal_i64(0);
344: }
345: static inline TCGv_i64 tcg_temp_local_new_i64(void)
346: {
347: return tcg_temp_new_internal_i64(1);
348: }
349: void tcg_temp_free_i64(TCGv_i64 arg);
350: char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
351:
352: void tcg_dump_info(FILE *f,
353: int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
354:
355: #define TCG_CT_ALIAS 0x80
356: #define TCG_CT_IALIAS 0x40
357: #define TCG_CT_REG 0x01
358: #define TCG_CT_CONST 0x02 /* any constant of register size */
359:
360: typedef struct TCGArgConstraint {
361: uint16_t ct;
362: uint8_t alias_index;
363: union {
364: TCGRegSet regs;
365: } u;
366: } TCGArgConstraint;
367:
368: #define TCG_MAX_OP_ARGS 16
369:
370: #define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic
371: block */
372: #define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers
373: and potentially update globals. */
374: #define TCG_OPF_SIDE_EFFECTS 0x04 /* instruction has side effects : it
375: cannot be removed if its output
376: are not used */
377:
378: typedef struct TCGOpDef {
379: const char *name;
380: uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
381: uint8_t flags;
382: uint16_t copy_size;
383: TCGArgConstraint *args_ct;
384: int *sorted_args;
385: } TCGOpDef;
386:
387: typedef struct TCGTargetOpDef {
388: int op;
389: const char *args_ct_str[TCG_MAX_OP_ARGS];
390: } TCGTargetOpDef;
391:
392: void tcg_target_init(TCGContext *s);
393: void tcg_target_qemu_prologue(TCGContext *s);
394:
395: #define tcg_abort() \
396: do {\
397: fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
398: abort();\
399: } while (0)
400:
401: void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
402:
403: #if TCG_TARGET_REG_BITS == 32
404: #define tcg_const_ptr tcg_const_i32
405: #define tcg_add_ptr tcg_add_i32
406: #define tcg_sub_ptr tcg_sub_i32
407: #define TCGv_ptr TCGv_i32
408: #define GET_TCGV_PTR GET_TCGV_I32
409: #define tcg_global_reg_new_ptr tcg_global_reg_new_i32
410: #define tcg_global_mem_new_ptr tcg_global_mem_new_i32
411: #define tcg_temp_new_ptr tcg_temp_new_i32
412: #define tcg_temp_free_ptr tcg_temp_free_i32
413: #else
414: #define tcg_const_ptr tcg_const_i64
415: #define tcg_add_ptr tcg_add_i64
416: #define tcg_sub_ptr tcg_sub_i64
417: #define TCGv_ptr TCGv_i64
418: #define GET_TCGV_PTR GET_TCGV_I64
419: #define tcg_global_reg_new_ptr tcg_global_reg_new_i64
420: #define tcg_global_mem_new_ptr tcg_global_mem_new_i64
421: #define tcg_temp_new_ptr tcg_temp_new_i64
422: #define tcg_temp_free_ptr tcg_temp_free_i64
423: #endif
424:
425: void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
426: int sizemask, TCGArg ret, int nargs, TCGArg *args);
427:
428: void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
429: int c, int right, int arith);
430:
431: /* only used for debugging purposes */
432: void tcg_register_helper(void *func, const char *name);
433: const char *tcg_helper_get_name(TCGContext *s, void *func);
434: void tcg_dump_ops(TCGContext *s, FILE *outfile);
435:
436: void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
437: TCGv_i32 tcg_const_i32(int32_t val);
438: TCGv_i64 tcg_const_i64(int64_t val);
439: TCGv_i32 tcg_const_local_i32(int32_t val);
440: TCGv_i64 tcg_const_local_i64(int64_t val);
441:
442: void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
443: int label_index, long addend);
444: const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
445: unsigned int dead_iargs);
446:
447: /* tcg-runtime.c */
448: int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2);
449: int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2);
450: int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2);
451: int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2);
452: int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2);
453: uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2);
454: uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2);
455:
456: extern uint8_t code_gen_prologue[];
457: #if defined(_ARCH_PPC) && !defined(_ARCH_PPC64)
458: #define tcg_qemu_tb_exec(tb_ptr) \
459: ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr)
460: #else
461: #define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
462: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.