diff options
Diffstat (limited to 'tcg/tcg.h')
-rw-r--r-- | tcg/tcg.h | 79 |
1 files changed, 58 insertions, 21 deletions
@@ -79,6 +79,7 @@ typedef uint64_t TCGRegSet; #define TCG_TARGET_HAS_nand_i64 0 #define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_deposit_i64 0 +#define TCG_TARGET_HAS_movcond_i64 0 #endif #ifndef TCG_TARGET_deposit_i32_valid @@ -265,18 +266,28 @@ typedef int TCGv_i64; #define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1) #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1)) +/* Conditions. Note that these are layed out for easy manipulation by + the the functions below: + bit 0 is used for inverting; + bit 1 is signed, + bit 2 is unsigned, + bit 3 is used with bit 0 for swapping signed/unsigned. */ typedef enum { - TCG_COND_EQ, - TCG_COND_NE, - TCG_COND_LT, - TCG_COND_GE, - TCG_COND_LE, - TCG_COND_GT, + /* non-signed */ + TCG_COND_NEVER = 0 | 0 | 0 | 0, + TCG_COND_ALWAYS = 0 | 0 | 0 | 1, + TCG_COND_EQ = 8 | 0 | 0 | 0, + TCG_COND_NE = 8 | 0 | 0 | 1, + /* signed */ + TCG_COND_LT = 0 | 0 | 2 | 0, + TCG_COND_GE = 0 | 0 | 2 | 1, + TCG_COND_LE = 8 | 0 | 2 | 0, + TCG_COND_GT = 8 | 0 | 2 | 1, /* unsigned */ - TCG_COND_LTU, - TCG_COND_GEU, - TCG_COND_LEU, - TCG_COND_GTU, + TCG_COND_LTU = 0 | 4 | 0 | 0, + TCG_COND_GEU = 0 | 4 | 0 | 1, + TCG_COND_LEU = 8 | 4 | 0 | 0, + TCG_COND_GTU = 8 | 4 | 0 | 1, } TCGCond; /* Invert the sense of the comparison. */ @@ -288,13 +299,34 @@ static inline TCGCond tcg_invert_cond(TCGCond c) /* Swap the operands in a comparison. */ static inline TCGCond tcg_swap_cond(TCGCond c) { - int mask = (c < TCG_COND_LT ? 0 : c < TCG_COND_LTU ? 7 : 15); - return (TCGCond)(c ^ mask); + return c & 6 ? (TCGCond)(c ^ 9) : c; } +/* Create an "unsigned" version of a "signed" comparison. */ static inline TCGCond tcg_unsigned_cond(TCGCond c) { - return (c >= TCG_COND_LT && c <= TCG_COND_GT ? c + 4 : c); + return c & 2 ? (TCGCond)(c ^ 6) : c; +} + +/* Must a comparison be considered unsigned? */ +static inline bool is_unsigned_cond(TCGCond c) +{ + return (c & 4) != 0; +} + +/* Create a "high" version of a double-word comparison. + This removes equality from a LTE or GTE comparison. */ +static inline TCGCond tcg_high_cond(TCGCond c) +{ + switch (c) { + case TCG_COND_GE: + case TCG_COND_LE: + case TCG_COND_GEU: + case TCG_COND_LEU: + return (TCGCond)(c ^ 8); + default: + return c; + } } #define TEMP_VAL_DEAD 0 @@ -335,7 +367,6 @@ struct TCGContext { TCGPool *pool_first, *pool_current, *pool_first_large; TCGLabel *labels; int nb_labels; - TCGTemp *temps; /* globals first, temps after */ int nb_globals; int nb_temps; /* index of free temps, -1 if none */ @@ -343,7 +374,7 @@ struct TCGContext { /* goto_tb support */ uint8_t *code_buf; - unsigned long *tb_next; + uintptr_t *tb_next; uint16_t *tb_next_offset; uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */ @@ -361,7 +392,7 @@ struct TCGContext { int frame_reg; uint8_t *code_ptr; - TCGTemp static_temps[TCG_MAX_TEMPS]; + TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */ TCGHelperInfo *helpers; int nb_helpers; @@ -382,12 +413,14 @@ struct TCGContext { int64_t interm_time; int64_t code_time; int64_t la_time; + int64_t opt_time; int64_t restore_count; int64_t restore_time; #endif #ifdef CONFIG_DEBUG_TCG int temps_in_use; + int goto_tb_issue_mask; #endif }; @@ -458,11 +491,6 @@ static inline TCGv_i64 tcg_temp_local_new_i64(void) void tcg_temp_free_i64(TCGv_i64 arg); char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg); -static inline bool tcg_arg_is_local(TCGContext *s, TCGArg arg) -{ - return s->temps[arg].temp_local; -} - #if defined(CONFIG_DEBUG_TCG) /* If you call tcg_clear_temp_count() at the start of a section of * code which is not supposed to leak any TCG temporaries, then @@ -533,6 +561,15 @@ do {\ abort();\ } while (0) +#ifdef CONFIG_DEBUG_TCG +# define tcg_debug_assert(X) do { assert(X); } while (0) +#elif QEMU_GNUC_PREREQ(4, 5) +# define tcg_debug_assert(X) \ + do { if (!(X)) { __builtin_unreachable(); } } while (0) +#else +# define tcg_debug_assert(X) do { (void)(X); } while (0) +#endif + void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs); #if TCG_TARGET_REG_BITS == 32 |