Message ID | 20220308015358.188499-2-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | s390x/tcg: Implement Vector-Enhancements Facility 2 | expand |
On 08.03.22 02:53, Richard Henderson wrote: > Swap half-words (16-bit) and words (32-bit) within a larger value. > Mirrors functions of the same names within include/qemu/bitops.h. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > include/tcg/tcg-op.h | 6 ++++++ > tcg/tcg-op.c | 30 ++++++++++++++++++++++++++++++ > 2 files changed, 36 insertions(+) > > diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h > index caa0a63612..b09b8b4a05 100644 > --- a/include/tcg/tcg-op.h > +++ b/include/tcg/tcg-op.h > @@ -332,6 +332,7 @@ void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg); > void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg); > void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags); > void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg); > +void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg); > void tcg_gen_smin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); > void tcg_gen_smax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); > void tcg_gen_umin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); > @@ -531,6 +532,8 @@ void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg); > void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags); > void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags); > void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg); > +void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg); > +void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg); > void tcg_gen_smin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); > void tcg_gen_smax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); > void tcg_gen_umin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); > @@ -1077,6 +1080,8 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t); > #define tcg_gen_bswap32_tl tcg_gen_bswap32_i64 > #define tcg_gen_bswap64_tl tcg_gen_bswap64_i64 > #define tcg_gen_bswap_tl tcg_gen_bswap64_i64 > +#define tcg_gen_hswap_tl tcg_gen_hswap_i64 > +#define tcg_gen_wswap_tl tcg_gen_wswap_i64 > #define tcg_gen_concat_tl_i64 tcg_gen_concat32_i64 > #define tcg_gen_extr_i64_tl tcg_gen_extr32_i64 > #define tcg_gen_andc_tl tcg_gen_andc_i64 > @@ -1192,6 +1197,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t); > #define tcg_gen_bswap16_tl tcg_gen_bswap16_i32 > #define tcg_gen_bswap32_tl(D, S, F) tcg_gen_bswap32_i32(D, S) > #define tcg_gen_bswap_tl tcg_gen_bswap32_i32 > +#define tcg_gen_hswap_tl tcg_gen_hswap_i32 > #define tcg_gen_concat_tl_i64 tcg_gen_concat_i32_i64 > #define tcg_gen_extr_i64_tl tcg_gen_extr_i64_i32 > #define tcg_gen_andc_tl tcg_gen_andc_i32 > diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c > index 65e1c94c2d..379adb4b9f 100644 > --- a/tcg/tcg-op.c > +++ b/tcg/tcg-op.c > @@ -1056,6 +1056,12 @@ void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg) > } > } > > +void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg) > +{ > + /* Swapping 2 16-bit elements is a rotate. */ > + tcg_gen_rotli_i32(ret, arg, 16); > +} > + > void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) > { > tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b); > @@ -1792,6 +1798,30 @@ void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) > } > } > > +void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg) > +{ > + uint64_t m = 0x0000ffff0000ffffull; > + TCGv_i64 t0 = tcg_temp_new_i64(); > + TCGv_i64 t1 = tcg_temp_new_i64(); > + > + /* See include/qemu/bitops.h, hswap64. */ > + tcg_gen_rotli_i64(t1, arg, 32);> + tcg_gen_andi_i64(t0, t1, m); > + tcg_gen_shri_i64(t1, t1, 16); > + tcg_gen_shli_i64(t0, t0, 16); I'd flip these two lines into tcg_gen_shli_i64(t0, t0, 16); tcg_gen_shri_i64(t1, t1, 16); To make it easier to map to hswap64(). Reviewed-by: David Hildenbrand <david@redhat.com>
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h index caa0a63612..b09b8b4a05 100644 --- a/include/tcg/tcg-op.h +++ b/include/tcg/tcg-op.h @@ -332,6 +332,7 @@ void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg); void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg); void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags); void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg); +void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg); void tcg_gen_smin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_smax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_umin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2); @@ -531,6 +532,8 @@ void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg); void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags); void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags); void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg); +void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg); +void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg); void tcg_gen_smin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_smax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_umin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2); @@ -1077,6 +1080,8 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t); #define tcg_gen_bswap32_tl tcg_gen_bswap32_i64 #define tcg_gen_bswap64_tl tcg_gen_bswap64_i64 #define tcg_gen_bswap_tl tcg_gen_bswap64_i64 +#define tcg_gen_hswap_tl tcg_gen_hswap_i64 +#define tcg_gen_wswap_tl tcg_gen_wswap_i64 #define tcg_gen_concat_tl_i64 tcg_gen_concat32_i64 #define tcg_gen_extr_i64_tl tcg_gen_extr32_i64 #define tcg_gen_andc_tl tcg_gen_andc_i64 @@ -1192,6 +1197,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t); #define tcg_gen_bswap16_tl tcg_gen_bswap16_i32 #define tcg_gen_bswap32_tl(D, S, F) tcg_gen_bswap32_i32(D, S) #define tcg_gen_bswap_tl tcg_gen_bswap32_i32 +#define tcg_gen_hswap_tl tcg_gen_hswap_i32 #define tcg_gen_concat_tl_i64 tcg_gen_concat_i32_i64 #define tcg_gen_extr_i64_tl tcg_gen_extr_i64_i32 #define tcg_gen_andc_tl tcg_gen_andc_i32 diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 65e1c94c2d..379adb4b9f 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -1056,6 +1056,12 @@ void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg) } } +void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg) +{ + /* Swapping 2 16-bit elements is a rotate. */ + tcg_gen_rotli_i32(ret, arg, 16); +} + void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) { tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b); @@ -1792,6 +1798,30 @@ void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) } } +void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg) +{ + uint64_t m = 0x0000ffff0000ffffull; + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + + /* See include/qemu/bitops.h, hswap64. */ + tcg_gen_rotli_i64(t1, arg, 32); + tcg_gen_andi_i64(t0, t1, m); + tcg_gen_shri_i64(t1, t1, 16); + tcg_gen_shli_i64(t0, t0, 16); + tcg_gen_andi_i64(t1, t1, m); + tcg_gen_or_i64(ret, t0, t1); + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +} + +void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg) +{ + /* Swapping 2 32-bit elements is a rotate. */ + tcg_gen_rotli_i64(ret, arg, 32); +} + void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg) { if (TCG_TARGET_REG_BITS == 32) {
Swap half-words (16-bit) and words (32-bit) within a larger value. Mirrors functions of the same names within include/qemu/bitops.h. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- include/tcg/tcg-op.h | 6 ++++++ tcg/tcg-op.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+)