2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2008 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 #include "tcg-target.h"
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
40 #if TCG_TARGET_NB_REGS <= 32
41 typedef uint32_t TCGRegSet
;
42 #elif TCG_TARGET_NB_REGS <= 64
43 typedef uint64_t TCGRegSet
;
49 #define DEF(s, n, copy_size) INDEX_op_ ## s,
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)
66 typedef struct TCGRelocation
{
67 struct TCGRelocation
*next
;
70 tcg_target_long addend
;
73 typedef struct TCGLabel
{
76 tcg_target_ulong value
;
77 TCGRelocation
*first_reloc
;
81 typedef struct TCGPool
{
87 #define TCG_POOL_CHUNK_SIZE 32768
89 #define TCG_MAX_LABELS 512
91 #define TCG_MAX_TEMPS 256
95 #define TCG_TYPE_I32 0
96 #define TCG_TYPE_I64 1
98 #if TCG_TARGET_REG_BITS == 32
99 #define TCG_TYPE_PTR TCG_TYPE_I32
101 #define TCG_TYPE_PTR TCG_TYPE_I64
104 typedef tcg_target_ulong TCGArg
;
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) */
127 #define TEMP_VAL_DEAD 0
128 #define TEMP_VAL_REG 1
129 #define TEMP_VAL_MEM 2
130 #define TEMP_VAL_CONST 3
132 /* XXX: optimize memory layout */
133 typedef struct TCGTemp
{
140 tcg_target_long mem_offset
;
141 unsigned int fixed_reg
:1;
142 unsigned int mem_coherent
:1;
143 unsigned int mem_allocated
:1;
147 typedef struct TCGHelperInfo
{
152 typedef struct TCGContext TCGContext
;
154 typedef void TCGMacroFunc(TCGContext
*s
, int macro_id
, const int *dead_args
);
157 uint8_t *pool_cur
, *pool_end
;
158 TCGPool
*pool_first
, *pool_current
;
161 TCGTemp
*temps
; /* globals first, temps after */
164 /* constant indexes (end of temp array) */
168 /* goto_tb support */
170 unsigned long *tb_next
;
171 uint16_t *tb_next_offset
;
172 uint16_t *tb_jmp_offset
; /* != NULL if USE_DIRECT_JUMP */
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
;
186 TCGTemp static_temps
[TCG_MAX_TEMPS
];
188 TCGMacroFunc
*macro_func
;
189 TCGHelperInfo
*helpers
;
191 int allocated_helpers
;
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
[];
200 /* pool based memory allocation */
202 void *tcg_malloc_internal(TCGContext
*s
, int size
);
203 void tcg_pool_reset(TCGContext
*s
);
204 void tcg_pool_delete(TCGContext
*s
);
206 static inline void *tcg_malloc(int size
)
208 TCGContext
*s
= &tcg_ctx
;
209 uint8_t *ptr
, *ptr_end
;
210 size
= (size
+ sizeof(long) - 1) & ~(sizeof(long) - 1);
212 ptr_end
= ptr
+ size
;
213 if (unlikely(ptr_end
> s
->pool_end
)) {
214 return tcg_malloc_internal(&tcg_ctx
, size
);
216 s
->pool_cur
= ptr_end
;
221 void tcg_context_init(TCGContext
*s
);
222 void tcg_func_start(TCGContext
*s
);
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
);
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
,
234 int tcg_temp_new(TCGType type
);
235 char *tcg_get_arg_str(TCGContext
*s
, char *buf
, int buf_size
, TCGArg arg
);
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 */
242 typedef struct TCGArgConstraint
{
249 #define TCG_MAX_OP_ARGS 16
251 #define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic
253 #define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers */
255 typedef struct TCGOpDef
{
257 uint8_t nb_oargs
, nb_iargs
, nb_cargs
, nb_args
;
260 TCGArgConstraint
*args_ct
;
264 typedef struct TCGTargetOpDef
{
266 const char *args_ct_str
[TCG_MAX_OP_ARGS
];
269 extern TCGOpDef tcg_op_defs
[];
271 void tcg_target_init(TCGContext
*s
);
273 #define tcg_abort() \
275 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
279 void tcg_add_target_add_op_defs(const TCGTargetOpDef
*tdefs
);
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
);
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
);
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
);
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
302 #define tcg_const_ptr tcg_const_i64
303 #define tcg_add_ptr tcg_add_i64
304 #define tcg_sub_ptr tcg_sub_i64
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
);
315 const TCGArg
*dyngen_op(TCGContext
*s
, int opc
, const TCGArg
*opparam_ptr
);
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
);