00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "tcg-target.h"
00025
00026 #if TCG_TARGET_REG_BITS == 32
00027 typedef int32_t tcg_target_long;
00028 typedef uint32_t tcg_target_ulong;
00029 #define TCG_PRIlx PRIx32
00030 #define TCG_PRIld PRId32
00031 #elif TCG_TARGET_REG_BITS == 64
00032 typedef int64_t tcg_target_long;
00033 typedef uint64_t tcg_target_ulong;
00034 #define TCG_PRIlx PRIx64
00035 #define TCG_PRIld PRId64
00036 #else
00037 #error unsupported
00038 #endif
00039
00040 #if TCG_TARGET_NB_REGS <= 32
00041 typedef uint32_t TCGRegSet;
00042 #elif TCG_TARGET_NB_REGS <= 64
00043 typedef uint64_t TCGRegSet;
00044 #else
00045 #error unsupported
00046 #endif
00047
00048 enum {
00049 #define DEF(s, n, copy_size) INDEX_op_ ## s,
00050 #include "tcg-opc.h"
00051 #undef DEF
00052 NB_OPS,
00053 };
00054
00055 #define tcg_regset_clear(d) (d) = 0
00056 #define tcg_regset_set(d, s) (d) = (s)
00057 #define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg)
00058 #define tcg_regset_set_reg(d, r) (d) |= 1 << (r)
00059 #define tcg_regset_reset_reg(d, r) (d) &= ~(1 << (r))
00060 #define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
00061 #define tcg_regset_or(d, a, b) (d) = (a) | (b)
00062 #define tcg_regset_and(d, a, b) (d) = (a) & (b)
00063 #define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b)
00064 #define tcg_regset_not(d, a) (d) = ~(a)
00065
00066 typedef struct TCGRelocation {
00067 struct TCGRelocation *next;
00068 int type;
00069 uint8_t *ptr;
00070 tcg_target_long addend;
00071 } TCGRelocation;
00072
00073 typedef struct TCGLabel {
00074 int has_value;
00075 union {
00076 tcg_target_ulong value;
00077 TCGRelocation *first_reloc;
00078 } u;
00079 } TCGLabel;
00080
00081 typedef struct TCGPool {
00082 struct TCGPool *next;
00083 int size;
00084 uint8_t data[0] __attribute__ ((aligned));
00085 } TCGPool;
00086
00087 #define TCG_POOL_CHUNK_SIZE 32768
00088
00089 #define TCG_MAX_LABELS 512
00090
00091 #define TCG_MAX_TEMPS 512
00092
00093
00094
00095 #define TCG_STATIC_CALL_ARGS_SIZE 128
00096
00097 typedef int TCGType;
00098
00099 #define TCG_TYPE_I32 0
00100 #define TCG_TYPE_I64 1
00101 #define TCG_TYPE_COUNT 2
00102
00103 #if TCG_TARGET_REG_BITS == 32
00104 #define TCG_TYPE_PTR TCG_TYPE_I32
00105 #else
00106 #define TCG_TYPE_PTR TCG_TYPE_I64
00107 #endif
00108
00109 typedef tcg_target_ulong TCGArg;
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 #ifdef DEBUG_TCGV
00126
00127 typedef struct
00128 {
00129 int i32;
00130 } TCGv_i32;
00131
00132 typedef struct
00133 {
00134 int i64;
00135 } TCGv_i64;
00136
00137 #define MAKE_TCGV_I32(i) __extension__ \
00138 ({ TCGv_i32 make_tcgv_tmp = {i}; make_tcgv_tmp;})
00139 #define MAKE_TCGV_I64(i) __extension__ \
00140 ({ TCGv_i64 make_tcgv_tmp = {i}; make_tcgv_tmp;})
00141 #define GET_TCGV_I32(t) ((t).i32)
00142 #define GET_TCGV_I64(t) ((t).i64)
00143 #if TCG_TARGET_REG_BITS == 32
00144 #define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
00145 #define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
00146 #endif
00147
00148 #else
00149
00150 typedef int TCGv_i32;
00151 typedef int TCGv_i64;
00152 #define MAKE_TCGV_I32(x) (x)
00153 #define MAKE_TCGV_I64(x) (x)
00154 #define GET_TCGV_I32(t) (t)
00155 #define GET_TCGV_I64(t) (t)
00156 #if TCG_TARGET_REG_BITS == 32
00157 #define TCGV_LOW(t) (t)
00158 #define TCGV_HIGH(t) ((t) + 1)
00159 #endif
00160
00161 #endif
00162
00163
00164 #define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1)
00165 #define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1)
00166
00167
00168 #define TCG_CALL_TYPE_MASK 0x000f
00169 #define TCG_CALL_TYPE_STD 0x0000
00170 #define TCG_CALL_TYPE_REGPARM_1 0x0001
00171 #define TCG_CALL_TYPE_REGPARM_2 0x0002
00172 #define TCG_CALL_TYPE_REGPARM 0x0003
00173
00174
00175
00176 #define TCG_CALL_PURE 0x0010
00177
00178
00179 #define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1)
00180 #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1))
00181
00182 typedef enum {
00183 TCG_COND_EQ,
00184 TCG_COND_NE,
00185 TCG_COND_LT,
00186 TCG_COND_GE,
00187 TCG_COND_LE,
00188 TCG_COND_GT,
00189
00190 TCG_COND_LTU,
00191 TCG_COND_GEU,
00192 TCG_COND_LEU,
00193 TCG_COND_GTU,
00194 } TCGCond;
00195
00196 #define TEMP_VAL_DEAD 0
00197 #define TEMP_VAL_REG 1
00198 #define TEMP_VAL_MEM 2
00199 #define TEMP_VAL_CONST 3
00200
00201
00202 typedef struct TCGTemp {
00203 TCGType base_type;
00204 TCGType type;
00205 int val_type;
00206 int reg;
00207 tcg_target_long val;
00208 int mem_reg;
00209 tcg_target_long mem_offset;
00210 unsigned int fixed_reg:1;
00211 unsigned int mem_coherent:1;
00212 unsigned int mem_allocated:1;
00213 unsigned int temp_local:1;
00214
00215
00216 unsigned int temp_allocated:1;
00217
00218 int next_free_temp;
00219 const char *name;
00220 } TCGTemp;
00221
00222 typedef struct TCGHelperInfo {
00223 tcg_target_ulong func;
00224 const char *name;
00225 } TCGHelperInfo;
00226
00227 typedef struct TCGContext TCGContext;
00228
00229 struct TCGContext {
00230 uint8_t *pool_cur, *pool_end;
00231 TCGPool *pool_first, *pool_current;
00232 TCGLabel *labels;
00233 int nb_labels;
00234 TCGTemp *temps;
00235 int nb_globals;
00236 int nb_temps;
00237
00238 int first_free_temp[TCG_TYPE_COUNT * 2];
00239
00240
00241 uint8_t *code_buf;
00242 unsigned long *tb_next;
00243 uint16_t *tb_next_offset;
00244 uint16_t *tb_jmp_offset;
00245
00246
00247 uint16_t *op_dead_iargs;
00248
00249
00250
00251
00252 int reg_to_temp[TCG_TARGET_NB_REGS];
00253 TCGRegSet reserved_regs;
00254 tcg_target_long current_frame_offset;
00255 tcg_target_long frame_start;
00256 tcg_target_long frame_end;
00257 int frame_reg;
00258
00259 uint8_t *code_ptr;
00260 TCGTemp static_temps[TCG_MAX_TEMPS];
00261
00262 TCGHelperInfo *helpers;
00263 int nb_helpers;
00264 int allocated_helpers;
00265 int helpers_sorted;
00266
00267 #ifdef CONFIG_PROFILER
00268
00269 int64_t tb_count1;
00270 int64_t tb_count;
00271 int64_t op_count;
00272 int op_count_max;
00273 int64_t temp_count;
00274 int temp_count_max;
00275 int64_t del_op_count;
00276 int64_t code_in_len;
00277 int64_t code_out_len;
00278 int64_t interm_time;
00279 int64_t code_time;
00280 int64_t la_time;
00281 int64_t restore_count;
00282 int64_t restore_time;
00283 #endif
00284 };
00285
00286 extern TCGContext tcg_ctx;
00287 extern uint16_t *gen_opc_ptr;
00288 extern TCGArg *gen_opparam_ptr;
00289 extern uint16_t gen_opc_buf[];
00290 extern TCGArg gen_opparam_buf[];
00291
00292
00293
00294 void *tcg_malloc_internal(TCGContext *s, int size);
00295 void tcg_pool_reset(TCGContext *s);
00296 void tcg_pool_delete(TCGContext *s);
00297
00298 static inline void *tcg_malloc(int size)
00299 {
00300 TCGContext *s = &tcg_ctx;
00301 uint8_t *ptr, *ptr_end;
00302 size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
00303 ptr = s->pool_cur;
00304 ptr_end = ptr + size;
00305 if (unlikely(ptr_end > s->pool_end)) {
00306 return tcg_malloc_internal(&tcg_ctx, size);
00307 } else {
00308 s->pool_cur = ptr_end;
00309 return ptr;
00310 }
00311 }
00312
00313 void tcg_context_init(TCGContext *s);
00314 void tcg_func_start(TCGContext *s);
00315
00316 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
00317 int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
00318
00319 void tcg_set_frame(TCGContext *s, int reg,
00320 tcg_target_long start, tcg_target_long size);
00321
00322 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
00323 TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
00324 const char *name);
00325 TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
00326 static inline TCGv_i32 tcg_temp_new_i32(void)
00327 {
00328 return tcg_temp_new_internal_i32(0);
00329 }
00330 static inline TCGv_i32 tcg_temp_local_new_i32(void)
00331 {
00332 return tcg_temp_new_internal_i32(1);
00333 }
00334 void tcg_temp_free_i32(TCGv_i32 arg);
00335 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg);
00336
00337 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
00338 TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
00339 const char *name);
00340 TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
00341 static inline TCGv_i64 tcg_temp_new_i64(void)
00342 {
00343 return tcg_temp_new_internal_i64(0);
00344 }
00345 static inline TCGv_i64 tcg_temp_local_new_i64(void)
00346 {
00347 return tcg_temp_new_internal_i64(1);
00348 }
00349 void tcg_temp_free_i64(TCGv_i64 arg);
00350 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
00351
00352 void tcg_dump_info(FILE *f,
00353 int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
00354
00355 #define TCG_CT_ALIAS 0x80
00356 #define TCG_CT_IALIAS 0x40
00357 #define TCG_CT_REG 0x01
00358 #define TCG_CT_CONST 0x02
00359
00360 typedef struct TCGArgConstraint {
00361 uint16_t ct;
00362 uint8_t alias_index;
00363 union {
00364 TCGRegSet regs;
00365 } u;
00366 } TCGArgConstraint;
00367
00368 #define TCG_MAX_OP_ARGS 16
00369
00370 #define TCG_OPF_BB_END 0x01
00371
00372 #define TCG_OPF_CALL_CLOBBER 0x02
00373
00374 #define TCG_OPF_SIDE_EFFECTS 0x04
00375
00376
00377
00378 typedef struct TCGOpDef {
00379 const char *name;
00380 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
00381 uint8_t flags;
00382 uint16_t copy_size;
00383 TCGArgConstraint *args_ct;
00384 int *sorted_args;
00385 } TCGOpDef;
00386
00387 typedef struct TCGTargetOpDef {
00388 int op;
00389 const char *args_ct_str[TCG_MAX_OP_ARGS];
00390 } TCGTargetOpDef;
00391
00392 void tcg_target_init(TCGContext *s);
00393 void tcg_target_qemu_prologue(TCGContext *s);
00394
00395 #define tcg_abort() \
00396 do {\
00397 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
00398 abort();\
00399 } while (0)
00400
00401 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
00402
00403 #if TCG_TARGET_REG_BITS == 32
00404 #define tcg_const_ptr tcg_const_i32
00405 #define tcg_add_ptr tcg_add_i32
00406 #define tcg_sub_ptr tcg_sub_i32
00407 #define TCGv_ptr TCGv_i32
00408 #define GET_TCGV_PTR GET_TCGV_I32
00409 #define tcg_global_reg_new_ptr tcg_global_reg_new_i32
00410 #define tcg_global_mem_new_ptr tcg_global_mem_new_i32
00411 #define tcg_temp_new_ptr tcg_temp_new_i32
00412 #define tcg_temp_free_ptr tcg_temp_free_i32
00413 #else
00414 #define tcg_const_ptr tcg_const_i64
00415 #define tcg_add_ptr tcg_add_i64
00416 #define tcg_sub_ptr tcg_sub_i64
00417 #define TCGv_ptr TCGv_i64
00418 #define GET_TCGV_PTR GET_TCGV_I64
00419 #define tcg_global_reg_new_ptr tcg_global_reg_new_i64
00420 #define tcg_global_mem_new_ptr tcg_global_mem_new_i64
00421 #define tcg_temp_new_ptr tcg_temp_new_i64
00422 #define tcg_temp_free_ptr tcg_temp_free_i64
00423 #endif
00424
00425 void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
00426 int sizemask, TCGArg ret, int nargs, TCGArg *args);
00427
00428 void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
00429 int c, int right, int arith);
00430
00431
00432 void tcg_register_helper(void *func, const char *name);
00433 const char *tcg_helper_get_name(TCGContext *s, void *func);
00434 void tcg_dump_ops(TCGContext *s, FILE *outfile);
00435
00436 void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
00437 TCGv_i32 tcg_const_i32(int32_t val);
00438 TCGv_i64 tcg_const_i64(int64_t val);
00439 TCGv_i32 tcg_const_local_i32(int32_t val);
00440 TCGv_i64 tcg_const_local_i64(int64_t val);
00441
00442 void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
00443 int label_index, long addend);
00444 const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
00445 unsigned int dead_iargs);
00446
00447
00448 int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2);
00449 int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2);
00450 int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2);
00451 int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2);
00452 int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2);
00453 uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2);
00454 uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2);
00455
00456 extern uint8_t code_gen_prologue[];
00457 #if defined(_ARCH_PPC) && !defined(_ARCH_PPC64)
00458 #define tcg_qemu_tb_exec(tb_ptr) \
00459 ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr)
00460 #else
00461 #define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
00462 #endif