diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-05-03 11:25:14 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-05-03 11:25:14 +0100 |
commit | 59255887e6cafeff747250d2613003a41d1d9dff (patch) | |
tree | e77c46b175d180bfdd263284878130ee36c340f8 | |
parent | 98bae9c4afb4f5c1ee1c9ffbb2e9708df9fddbed (diff) | |
parent | 6001f7729e12dd1d810291e4cbf83cee8e07441d (diff) |
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20180502' into staging
Queued TCG patches
# gpg: Signature made Wed 02 May 2018 18:43:33 BST
# gpg: using RSA key 64DF38E8AF7E215F
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>"
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F
* remotes/rth/tags/pull-tcg-20180502:
tcg: workaround branch instruction overflow in tcg_out_qemu_ld/st
tcg: Improve TCGv_ptr support
tcg: Allow wider vectors for cmp and mul
tcg/arm: Fix memory barrier encoding
tcg: Document INDEX_mul[us]h_*
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | target/hppa/translate.c | 16 | ||||
-rw-r--r-- | tcg/README | 8 | ||||
-rw-r--r-- | tcg/arm/tcg-target.inc.c | 4 | ||||
-rw-r--r-- | tcg/tcg-ldst.inc.c | 8 | ||||
-rw-r--r-- | tcg/tcg-op-vec.c | 8 | ||||
-rw-r--r-- | tcg/tcg-op.h | 91 | ||||
-rw-r--r-- | tcg/tcg.c | 33 | ||||
-rw-r--r-- | tcg/tcg.h | 88 |
8 files changed, 150 insertions, 106 deletions
diff --git a/target/hppa/translate.c b/target/hppa/translate.c index c532889b1f..cdc397308b 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -151,13 +151,7 @@ #define tcg_gen_qemu_ld_reg tcg_gen_qemu_ld_i64 #define tcg_gen_qemu_st_reg tcg_gen_qemu_st_i64 #define tcg_gen_atomic_xchg_reg tcg_gen_atomic_xchg_i64 -#if UINTPTR_MAX == UINT32_MAX -# define tcg_gen_trunc_reg_ptr(p, r) \ - tcg_gen_trunc_i64_i32(TCGV_PTR_TO_NAT(p), r) -#else -# define tcg_gen_trunc_reg_ptr(p, r) \ - tcg_gen_mov_i64(TCGV_PTR_TO_NAT(p), r) -#endif +#define tcg_gen_trunc_reg_ptr tcg_gen_trunc_i64_ptr #else #define TCGv_reg TCGv_i32 #define tcg_temp_new tcg_temp_new_i32 @@ -251,13 +245,7 @@ #define tcg_gen_qemu_ld_reg tcg_gen_qemu_ld_i32 #define tcg_gen_qemu_st_reg tcg_gen_qemu_st_i32 #define tcg_gen_atomic_xchg_reg tcg_gen_atomic_xchg_i32 -#if UINTPTR_MAX == UINT32_MAX -# define tcg_gen_trunc_reg_ptr(p, r) \ - tcg_gen_mov_i32(TCGV_PTR_TO_NAT(p), r) -#else -# define tcg_gen_trunc_reg_ptr(p, r) \ - tcg_gen_extu_i32_i64(TCGV_PTR_TO_NAT(p), r) -#endif +#define tcg_gen_trunc_reg_ptr tcg_gen_ext_i32_ptr #endif /* TARGET_REGISTER_BITS */ typedef struct DisasCond { diff --git a/tcg/README b/tcg/README index bb2ea5121b..a5237a9edb 100644 --- a/tcg/README +++ b/tcg/README @@ -431,6 +431,14 @@ double-word product T0. The later is returned in two single-word outputs. Similar to mulu2, except the two inputs T1 and T2 are signed. +* mulsh_i32/i64 t0, t1, t2 +* muluh_i32/i64 t0, t1, t2 + +Provide the high part of a signed or unsigned multiply, respectively. +If mulu2/muls2 are not provided by the backend, the tcg-op generator +can obtain the same results can be obtained by emitting a pair of +opcodes, mul+muluh/mulsh. + ********* Memory Barrier support * mb <$arg> diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c index dc83f3e5be..56a32a470f 100644 --- a/tcg/arm/tcg-target.inc.c +++ b/tcg/arm/tcg-target.inc.c @@ -159,8 +159,8 @@ typedef enum { INSN_STRD_IMM = 0x004000f0, INSN_STRD_REG = 0x000000f0, - INSN_DMB_ISH = 0x5bf07ff5, - INSN_DMB_MCR = 0xba0f07ee, + INSN_DMB_ISH = 0xf57ff05b, + INSN_DMB_MCR = 0xee070fba, /* Architected nop introduced in v6k. */ /* ??? This is an MSR (imm) 0,0,0 insn. Anyone know if this diff --git a/tcg/tcg-ldst.inc.c b/tcg/tcg-ldst.inc.c index 0e14cf4357..47f41b921b 100644 --- a/tcg/tcg-ldst.inc.c +++ b/tcg/tcg-ldst.inc.c @@ -30,7 +30,7 @@ typedef struct TCGLabelQemuLdst { TCGReg datahi_reg; /* reg index for high word to be loaded or stored */ tcg_insn_unit *raddr; /* gen code addr of the next IR of qemu_ld/st IR */ tcg_insn_unit *label_ptr[2]; /* label pointers to be updated */ - struct TCGLabelQemuLdst *next; + QSIMPLEQ_ENTRY(TCGLabelQemuLdst) next; } TCGLabelQemuLdst; @@ -46,7 +46,7 @@ static bool tcg_out_ldst_finalize(TCGContext *s) TCGLabelQemuLdst *lb; /* qemu_ld/st slow paths */ - for (lb = s->ldst_labels; lb != NULL; lb = lb->next) { + QSIMPLEQ_FOREACH(lb, &s->ldst_labels, next) { if (lb->is_ld) { tcg_out_qemu_ld_slow_path(s, lb); } else { @@ -72,7 +72,7 @@ static inline TCGLabelQemuLdst *new_ldst_label(TCGContext *s) { TCGLabelQemuLdst *l = tcg_malloc(sizeof(*l)); - l->next = s->ldst_labels; - s->ldst_labels = l; + QSIMPLEQ_INSERT_TAIL(&s->ldst_labels, l, next); + return l; } diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 70ec889bc1..2ca219734d 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -355,8 +355,8 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, TCGType type = rt->base_type; int can; - tcg_debug_assert(at->base_type == type); - tcg_debug_assert(bt->base_type == type); + tcg_debug_assert(at->base_type >= type); + tcg_debug_assert(bt->base_type >= type); can = tcg_can_emit_vec_op(INDEX_op_cmp_vec, type, vece); if (can > 0) { vec_gen_4(INDEX_op_cmp_vec, type, vece, ri, ai, bi, cond); @@ -377,8 +377,8 @@ void tcg_gen_mul_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b) TCGType type = rt->base_type; int can; - tcg_debug_assert(at->base_type == type); - tcg_debug_assert(bt->base_type == type); + tcg_debug_assert(at->base_type >= type); + tcg_debug_assert(bt->base_type >= type); can = tcg_can_emit_vec_op(INDEX_op_mul_vec, type, vece); if (can > 0) { vec_gen_3(INDEX_op_mul_vec, type, vece, ri, ai, bi); diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 75bb55aeac..5d2c91a1b6 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -1137,25 +1137,74 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t); #endif #if UINTPTR_MAX == UINT32_MAX -# define tcg_gen_ld_ptr(R, A, O) \ - tcg_gen_ld_i32(TCGV_PTR_TO_NAT(R), (A), (O)) -# define tcg_gen_discard_ptr(A) \ - tcg_gen_discard_i32(TCGV_PTR_TO_NAT(A)) -# define tcg_gen_add_ptr(R, A, B) \ - tcg_gen_add_i32(TCGV_PTR_TO_NAT(R), TCGV_PTR_TO_NAT(A), TCGV_PTR_TO_NAT(B)) -# define tcg_gen_addi_ptr(R, A, B) \ - tcg_gen_addi_i32(TCGV_PTR_TO_NAT(R), TCGV_PTR_TO_NAT(A), (B)) -# define tcg_gen_ext_i32_ptr(R, A) \ - tcg_gen_mov_i32(TCGV_PTR_TO_NAT(R), (A)) +# define PTR i32 +# define NAT TCGv_i32 #else -# define tcg_gen_ld_ptr(R, A, O) \ - tcg_gen_ld_i64(TCGV_PTR_TO_NAT(R), (A), (O)) -# define tcg_gen_discard_ptr(A) \ - tcg_gen_discard_i64(TCGV_PTR_TO_NAT(A)) -# define tcg_gen_add_ptr(R, A, B) \ - tcg_gen_add_i64(TCGV_PTR_TO_NAT(R), TCGV_PTR_TO_NAT(A), TCGV_PTR_TO_NAT(B)) -# define tcg_gen_addi_ptr(R, A, B) \ - tcg_gen_addi_i64(TCGV_PTR_TO_NAT(R), TCGV_PTR_TO_NAT(A), (B)) -# define tcg_gen_ext_i32_ptr(R, A) \ - tcg_gen_ext_i32_i64(TCGV_PTR_TO_NAT(R), (A)) -#endif /* UINTPTR_MAX == UINT32_MAX */ +# define PTR i64 +# define NAT TCGv_i64 +#endif + +static inline void tcg_gen_ld_ptr(TCGv_ptr r, TCGv_ptr a, intptr_t o) +{ + glue(tcg_gen_ld_,PTR)((NAT)r, a, o); +} + +static inline void tcg_gen_discard_ptr(TCGv_ptr a) +{ + glue(tcg_gen_discard_,PTR)((NAT)a); +} + +static inline void tcg_gen_add_ptr(TCGv_ptr r, TCGv_ptr a, TCGv_ptr b) +{ + glue(tcg_gen_add_,PTR)((NAT)r, (NAT)a, (NAT)b); +} + +static inline void tcg_gen_addi_ptr(TCGv_ptr r, TCGv_ptr a, intptr_t b) +{ + glue(tcg_gen_addi_,PTR)((NAT)r, (NAT)a, b); +} + +static inline void tcg_gen_brcondi_ptr(TCGCond cond, TCGv_ptr a, + intptr_t b, TCGLabel *label) +{ + glue(tcg_gen_brcondi_,PTR)(cond, (NAT)a, b, label); +} + +static inline void tcg_gen_ext_i32_ptr(TCGv_ptr r, TCGv_i32 a) +{ +#if UINTPTR_MAX == UINT32_MAX + tcg_gen_mov_i32((NAT)r, a); +#else + tcg_gen_ext_i32_i64((NAT)r, a); +#endif +} + +static inline void tcg_gen_trunc_i64_ptr(TCGv_ptr r, TCGv_i64 a) +{ +#if UINTPTR_MAX == UINT32_MAX + tcg_gen_extrl_i64_i32((NAT)r, a); +#else + tcg_gen_mov_i64((NAT)r, a); +#endif +} + +static inline void tcg_gen_extu_ptr_i64(TCGv_i64 r, TCGv_ptr a) +{ +#if UINTPTR_MAX == UINT32_MAX + tcg_gen_extu_i32_i64(r, (NAT)a); +#else + tcg_gen_mov_i64(r, (NAT)a); +#endif +} + +static inline void tcg_gen_trunc_ptr_i32(TCGv_i32 r, TCGv_ptr a) +{ +#if UINTPTR_MAX == UINT32_MAX + tcg_gen_mov_i32(r, (NAT)a); +#else + tcg_gen_extrl_i64_i32(r, (NAT)a); +#endif +} + +#undef PTR +#undef NAT @@ -980,7 +980,7 @@ TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base, return ts; } -static TCGTemp *tcg_temp_new_internal(TCGType type, int temp_local) +TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local) { TCGContext *s = tcg_ctx; TCGTemp *ts; @@ -1025,18 +1025,6 @@ static TCGTemp *tcg_temp_new_internal(TCGType type, int temp_local) return ts; } -TCGv_i32 tcg_temp_new_internal_i32(int temp_local) -{ - TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, temp_local); - return temp_tcgv_i32(t); -} - -TCGv_i64 tcg_temp_new_internal_i64(int temp_local) -{ - TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, temp_local); - return temp_tcgv_i64(t); -} - TCGv_vec tcg_temp_new_vec(TCGType type) { TCGTemp *t; @@ -1072,7 +1060,7 @@ TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match) return temp_tcgv_vec(t); } -static void tcg_temp_free_internal(TCGTemp *ts) +void tcg_temp_free_internal(TCGTemp *ts) { TCGContext *s = tcg_ctx; int k, idx; @@ -1093,21 +1081,6 @@ static void tcg_temp_free_internal(TCGTemp *ts) set_bit(idx, s->free_temps[k].l); } -void tcg_temp_free_i32(TCGv_i32 arg) -{ - tcg_temp_free_internal(tcgv_i32_temp(arg)); -} - -void tcg_temp_free_i64(TCGv_i64 arg) -{ - tcg_temp_free_internal(tcgv_i64_temp(arg)); -} - -void tcg_temp_free_vec(TCGv_vec arg) -{ - tcg_temp_free_internal(tcgv_vec_temp(arg)); -} - TCGv_i32 tcg_const_i32(int32_t val) { TCGv_i32 t0; @@ -3324,7 +3297,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) s->code_ptr = tb->tc.ptr; #ifdef TCG_TARGET_NEED_LDST_LABELS - s->ldst_labels = NULL; + QSIMPLEQ_INIT(&s->ldst_labels); #endif #ifdef TCG_TARGET_NEED_POOL_LABELS s->pool_labels = NULL; @@ -699,7 +699,7 @@ struct TCGContext { /* These structures are private to tcg-target.inc.c. */ #ifdef TCG_TARGET_NEED_LDST_LABELS - struct TCGLabelQemuLdst *ldst_labels; + QSIMPLEQ_HEAD(ldst_labels, TCGLabelQemuLdst) ldst_labels; #endif #ifdef TCG_TARGET_NEED_POOL_LABELS struct TCGLabelPoolData *pool_labels; @@ -890,15 +890,30 @@ void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size); TCGTemp *tcg_global_mem_new_internal(TCGType, TCGv_ptr, intptr_t, const char *); - -TCGv_i32 tcg_temp_new_internal_i32(int temp_local); -TCGv_i64 tcg_temp_new_internal_i64(int temp_local); +TCGTemp *tcg_temp_new_internal(TCGType, bool); +void tcg_temp_free_internal(TCGTemp *); TCGv_vec tcg_temp_new_vec(TCGType type); TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match); -void tcg_temp_free_i32(TCGv_i32 arg); -void tcg_temp_free_i64(TCGv_i64 arg); -void tcg_temp_free_vec(TCGv_vec arg); +static inline void tcg_temp_free_i32(TCGv_i32 arg) +{ + tcg_temp_free_internal(tcgv_i32_temp(arg)); +} + +static inline void tcg_temp_free_i64(TCGv_i64 arg) +{ + tcg_temp_free_internal(tcgv_i64_temp(arg)); +} + +static inline void tcg_temp_free_ptr(TCGv_ptr arg) +{ + tcg_temp_free_internal(tcgv_ptr_temp(arg)); +} + +static inline void tcg_temp_free_vec(TCGv_vec arg) +{ + tcg_temp_free_internal(tcgv_vec_temp(arg)); +} static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset, const char *name) @@ -909,12 +924,14 @@ static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset, static inline TCGv_i32 tcg_temp_new_i32(void) { - return tcg_temp_new_internal_i32(0); + TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, false); + return temp_tcgv_i32(t); } static inline TCGv_i32 tcg_temp_local_new_i32(void) { - return tcg_temp_new_internal_i32(1); + TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, true); + return temp_tcgv_i32(t); } static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset, @@ -926,12 +943,33 @@ static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset, static inline TCGv_i64 tcg_temp_new_i64(void) { - return tcg_temp_new_internal_i64(0); + TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, false); + return temp_tcgv_i64(t); } static inline TCGv_i64 tcg_temp_local_new_i64(void) { - return tcg_temp_new_internal_i64(1); + TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, true); + return temp_tcgv_i64(t); +} + +static inline TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t offset, + const char *name) +{ + TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_PTR, reg, offset, name); + return temp_tcgv_ptr(t); +} + +static inline TCGv_ptr tcg_temp_new_ptr(void) +{ + TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, false); + return temp_tcgv_ptr(t); +} + +static inline TCGv_ptr tcg_temp_local_new_ptr(void) +{ + TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, true); + return temp_tcgv_ptr(t); } #if defined(CONFIG_DEBUG_TCG) @@ -1009,26 +1047,6 @@ do {\ abort();\ } while (0) -#if UINTPTR_MAX == UINT32_MAX -static inline TCGv_ptr TCGV_NAT_TO_PTR(TCGv_i32 n) { return (TCGv_ptr)n; } -static inline TCGv_i32 TCGV_PTR_TO_NAT(TCGv_ptr n) { return (TCGv_i32)n; } - -#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((intptr_t)(V))) -#define tcg_global_mem_new_ptr(R, O, N) \ - TCGV_NAT_TO_PTR(tcg_global_mem_new_i32((R), (O), (N))) -#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i32()) -#define tcg_temp_free_ptr(T) tcg_temp_free_i32(TCGV_PTR_TO_NAT(T)) -#else -static inline TCGv_ptr TCGV_NAT_TO_PTR(TCGv_i64 n) { return (TCGv_ptr)n; } -static inline TCGv_i64 TCGV_PTR_TO_NAT(TCGv_ptr n) { return (TCGv_i64)n; } - -#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((intptr_t)(V))) -#define tcg_global_mem_new_ptr(R, O, N) \ - TCGV_NAT_TO_PTR(tcg_global_mem_new_i64((R), (O), (N))) -#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i64()) -#define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T)) -#endif - bool tcg_op_supported(TCGOpcode op); void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args); @@ -1052,6 +1070,14 @@ TCGv_vec tcg_const_ones_vec(TCGType); TCGv_vec tcg_const_zeros_vec_matching(TCGv_vec); TCGv_vec tcg_const_ones_vec_matching(TCGv_vec); +#if UINTPTR_MAX == UINT32_MAX +# define tcg_const_ptr(x) ((TCGv_ptr)tcg_const_i32((intptr_t)(x))) +# define tcg_const_local_ptr(x) ((TCGv_ptr)tcg_const_local_i32((intptr_t)(x))) +#else +# define tcg_const_ptr(x) ((TCGv_ptr)tcg_const_i64((intptr_t)(x))) +# define tcg_const_local_ptr(x) ((TCGv_ptr)tcg_const_local_i64((intptr_t)(x))) +#endif + TCGLabel *gen_new_label(void); /** |