From a85833933628384d74ec412024d55cf012640287 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 31 Jul 2017 22:02:31 -0700 Subject: tcg: Move USE_DIRECT_JUMP discriminator to tcg/cpu/tcg-target.h Replace the USE_DIRECT_JUMP ifdef with a TCG_TARGET_HAS_direct_jump boolean test. Replace the tb_set_jmp_target1 ifdef with an unconditional function tb_target_set_jmp_target. While we're touching all backends, add a parameter for tb->tc_ptr; we're going to need it shortly for some backends. Move tb_set_jmp_target and tb_add_jump from exec-all.h to cpu-exec.c. This opens the possibility for TCG_TARGET_HAS_direct_jump to be a runtime decision -- based on host cpu capabilities, the size of code_gen_buffer, or a future debugging switch. Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.h | 5 ++++- tcg/aarch64/tcg-target.inc.c | 13 +++++-------- tcg/arm/tcg-target.h | 6 +++++- tcg/i386/tcg-target.h | 9 +++++++++ tcg/mips/tcg-target.h | 5 ++++- tcg/mips/tcg-target.inc.c | 3 ++- tcg/ppc/tcg-target.h | 2 ++ tcg/ppc/tcg-target.inc.c | 6 ++++-- tcg/s390/tcg-target.h | 10 ++++++++++ tcg/sparc/tcg-target.h | 3 +++ tcg/sparc/tcg-target.inc.c | 3 ++- tcg/tcg.h | 4 ++-- tcg/tci/tcg-target.h | 9 +++++++++ 13 files changed, 61 insertions(+), 17 deletions(-) (limited to 'tcg') diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index b41a248bee..719861fe3e 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -111,12 +111,15 @@ typedef enum { #define TCG_TARGET_HAS_muls2_i64 0 #define TCG_TARGET_HAS_muluh_i64 1 #define TCG_TARGET_HAS_mulsh_i64 1 +#define TCG_TARGET_HAS_direct_jump 1 + +#define TCG_TARGET_DEFAULT_MO (0) static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { __builtin___clear_cache((char *)start, (char *)stop); } -#define TCG_TARGET_DEFAULT_MO (0) +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); #endif /* AARCH64_TCG_TARGET_H */ diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c index 04bc369a92..a1e5dd2f03 100644 --- a/tcg/aarch64/tcg-target.inc.c +++ b/tcg/aarch64/tcg-target.inc.c @@ -871,9 +871,8 @@ static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *target) } } -#ifdef USE_DIRECT_JUMP - -void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr) +void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, + uintptr_t addr) { tcg_insn_unit i1, i2; TCGType rt = TCG_TYPE_I64; @@ -898,8 +897,6 @@ void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr) flush_icache_range(jmp_addr, jmp_addr + 8); } -#endif - static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l) { if (!l->has_value) { @@ -1412,7 +1409,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: if (s->tb_jmp_insn_offset != NULL) { - /* USE_DIRECT_JUMP */ + /* TCG_TARGET_HAS_direct_jump */ /* Ensure that ADRP+ADD are 8-byte aligned so that an atomic write can be used to patch the target address. */ if ((uintptr_t)s->code_ptr & 7) { @@ -1420,11 +1417,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, } s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s); /* actual branch destination will be patched by - aarch64_tb_set_jmp_target later. */ + tb_target_set_jmp_target later. */ tcg_out_insn(s, 3406, ADRP, TCG_REG_TMP, 0); tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_TMP, TCG_REG_TMP, 0); } else { - /* !USE_DIRECT_JUMP */ + /* !TCG_TARGET_HAS_direct_jump */ tcg_debug_assert(s->tb_jmp_target_addr != NULL); intptr_t offset = tcg_pcrel_diff(s, (s->tb_jmp_target_addr + a0)) >> 2; tcg_out_insn(s, 3305, LDR, offset, TCG_REG_TMP); diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index a38be15a39..7117ebf4fc 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -124,16 +124,20 @@ extern bool use_idiv_instructions; #define TCG_TARGET_HAS_div_i32 use_idiv_instructions #define TCG_TARGET_HAS_rem_i32 0 #define TCG_TARGET_HAS_goto_ptr 1 +#define TCG_TARGET_HAS_direct_jump 0 enum { TCG_AREG0 = TCG_REG_R6, }; +#define TCG_TARGET_DEFAULT_MO (0) + static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { __builtin___clear_cache((char *) start, (char *) stop); } -#define TCG_TARGET_DEFAULT_MO (0) +/* not defined -- call should be eliminated at compile time */ +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); #endif diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index 73a15f7e80..2fd28fa6a5 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -108,6 +108,7 @@ extern bool have_popcnt; #define TCG_TARGET_HAS_muluh_i32 0 #define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_goto_ptr 1 +#define TCG_TARGET_HAS_direct_jump 1 #if TCG_TARGET_REG_BITS == 64 #define TCG_TARGET_HAS_extrl_i64_i32 0 @@ -166,6 +167,14 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { } +static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, + uintptr_t jmp_addr, uintptr_t addr) +{ + /* patch the branch destination */ + atomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4)); + /* no need to flush icache explicitly */ +} + /* This defines the natural memory order supported by this * architecture before guarantees made by various barrier * instructions. diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index e9558d15bc..928a762bd7 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -131,6 +131,7 @@ extern bool use_mips32r2_instructions; #define TCG_TARGET_HAS_mulsh_i32 1 #define TCG_TARGET_HAS_bswap32_i32 1 #define TCG_TARGET_HAS_goto_ptr 1 +#define TCG_TARGET_HAS_direct_jump 1 #if TCG_TARGET_REG_BITS == 64 #define TCG_TARGET_HAS_add2_i32 0 @@ -201,11 +202,13 @@ extern bool use_mips32r2_instructions; #include #endif +#define TCG_TARGET_DEFAULT_MO (0) + static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { cacheflush ((void *)start, stop-start, ICACHE); } -#define TCG_TARGET_DEFAULT_MO (0) +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); #endif diff --git a/tcg/mips/tcg-target.inc.c b/tcg/mips/tcg-target.inc.c index 1a8169f5fc..04f8c839fe 100644 --- a/tcg/mips/tcg-target.inc.c +++ b/tcg/mips/tcg-target.inc.c @@ -2642,7 +2642,8 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */ } -void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) +void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, + uintptr_t addr) { atomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2)); flush_icache_range(jmp_addr, jmp_addr + 4); diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index 5a092b038a..aa44e715d8 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -83,6 +83,7 @@ extern bool have_isa_3_00; #define TCG_TARGET_HAS_muluh_i32 1 #define TCG_TARGET_HAS_mulsh_i32 1 #define TCG_TARGET_HAS_goto_ptr 1 +#define TCG_TARGET_HAS_direct_jump 1 #if TCG_TARGET_REG_BITS == 64 #define TCG_TARGET_HAS_add2_i32 0 @@ -124,6 +125,7 @@ extern bool have_isa_3_00; #endif void flush_icache_range(uintptr_t start, uintptr_t stop); +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); #define TCG_TARGET_DEFAULT_MO (0) diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c index 1f690df20d..018c240f6d 100644 --- a/tcg/ppc/tcg-target.inc.c +++ b/tcg/ppc/tcg-target.inc.c @@ -1296,7 +1296,8 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0) } #ifdef __powerpc64__ -void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr) +void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, + uintptr_t addr) { tcg_insn_unit i1, i2; uint64_t pair; @@ -1328,7 +1329,8 @@ void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr) flush_icache_range(jmp_addr, jmp_addr + 8); } #else -void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr) +void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, + uintptr_t addr) { intptr_t diff = addr - jmp_addr; tcg_debug_assert(in_range_b(diff)); diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h index bedda5edf6..31a9eb4ac7 100644 --- a/tcg/s390/tcg-target.h +++ b/tcg/s390/tcg-target.h @@ -95,6 +95,7 @@ extern uint64_t s390_facilities; #define TCG_TARGET_HAS_extrl_i64_i32 0 #define TCG_TARGET_HAS_extrh_i64_i32 0 #define TCG_TARGET_HAS_goto_ptr 1 +#define TCG_TARGET_HAS_direct_jump 1 #define TCG_TARGET_HAS_div2_i64 1 #define TCG_TARGET_HAS_rot_i64 1 @@ -145,4 +146,13 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { } +static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, + uintptr_t jmp_addr, uintptr_t addr) +{ + /* patch the branch destination */ + intptr_t disp = addr - (jmp_addr - 2); + atomic_set((int32_t *)jmp_addr, disp / 2); + /* no need to flush icache explicitly */ +} + #endif diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index 4515c9ab48..da98743817 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -124,6 +124,7 @@ extern bool use_vis3_instructions; #define TCG_TARGET_HAS_muluh_i32 0 #define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_goto_ptr 1 +#define TCG_TARGET_HAS_direct_jump 1 #define TCG_TARGET_HAS_extrl_i64_i32 1 #define TCG_TARGET_HAS_extrh_i64_i32 1 @@ -172,4 +173,6 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop) } } +void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); + #endif diff --git a/tcg/sparc/tcg-target.inc.c b/tcg/sparc/tcg-target.inc.c index 18afce2f87..06cabbedf5 100644 --- a/tcg/sparc/tcg-target.inc.c +++ b/tcg/sparc/tcg-target.inc.c @@ -1708,7 +1708,8 @@ void tcg_register_jit(void *buf, size_t buf_size) tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); } -void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) +void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, + uintptr_t addr) { uint32_t *ptr = (uint32_t *)jmp_addr; uintptr_t disp = addr - jmp_addr; diff --git a/tcg/tcg.h b/tcg/tcg.h index 17b7750ee6..46957d9bd7 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -652,8 +652,8 @@ struct TCGContext { /* goto_tb support */ tcg_insn_unit *code_buf; uint16_t *tb_jmp_reset_offset; /* tb->jmp_reset_offset */ - uint16_t *tb_jmp_insn_offset; /* tb->jmp_insn_offset if USE_DIRECT_JUMP */ - uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_addr if !USE_DIRECT_JUMP */ + uintptr_t *tb_jmp_insn_offset; /* tb->jmp_target_arg if direct_jump */ + uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_arg if !direct_jump */ TCGRegSet reserved_regs; intptr_t current_frame_offset; diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index 8df628a319..26140d78cb 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -86,6 +86,7 @@ #define TCG_TARGET_HAS_muluh_i32 0 #define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_goto_ptr 0 +#define TCG_TARGET_HAS_direct_jump 1 #if TCG_TARGET_REG_BITS == 64 #define TCG_TARGET_HAS_extrl_i64_i32 0 @@ -197,4 +198,12 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop) We prefer consistency across hosts on this. */ #define TCG_TARGET_DEFAULT_MO (0) +static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, + uintptr_t jmp_addr, uintptr_t addr) +{ + /* patch the branch destination */ + atomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4)); + /* no need to flush icache explicitly */ +} + #endif /* TCG_TARGET_H */ -- cgit v1.2.3