diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index c413b28bd..da3aa54f3 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -1297,6 +1297,20 @@ static inline void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg) tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); } +/* Note: we assume the six high bytes are set to zero */ +static inline void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg) +{ + tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); + tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg)); +} + +/* Note: we assume the four high bytes are set to zero */ +static inline void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg) +{ + tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); + tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg)); +} + static inline void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) { TCGv_i32 t0, t1; @@ -1378,6 +1392,50 @@ static inline void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg) tcg_gen_ext32s_i64(ret, MAKE_TCGV_I64(GET_TCGV_I32(arg))); } +/* Note: we assume the six high bytes are set to zero */ +static inline void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg) +{ +#ifdef TCG_TARGET_HAS_bswap16_i64 + tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg); +#else + TCGv_i64 t0 = tcg_temp_new_i64(); + + tcg_gen_ext8u_i64(t0, arg); + tcg_gen_shli_i64(t0, t0, 8); + tcg_gen_shri_i64(ret, arg, 8); + tcg_gen_or_i64(ret, ret, t0); + tcg_temp_free_i64(t0); +#endif +} + +/* Note: we assume the four high bytes are set to zero */ +static inline void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg) +{ +#ifdef TCG_TARGET_HAS_bswap32_i64 + tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg); +#else + TCGv_i64 t0, t1; + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + + tcg_gen_shli_i64(t0, arg, 24); + tcg_gen_ext32u_i64(t0, t0); + + tcg_gen_andi_i64(t1, arg, 0x0000ff00); + tcg_gen_shli_i64(t1, t1, 8); + tcg_gen_or_i64(t0, t0, t1); + + tcg_gen_shri_i64(t1, arg, 8); + tcg_gen_andi_i64(t1, t1, 0x0000ff00); + tcg_gen_or_i64(t0, t0, t1); + + tcg_gen_shri_i64(t1, arg, 24); + tcg_gen_or_i64(ret, t0, t1); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +#endif +} + static inline void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) { #ifdef TCG_TARGET_HAS_bswap64_i64 diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h index b5fc197d6..3a095fce1 100644 --- a/tcg/tcg-opc.h +++ b/tcg/tcg-opc.h @@ -152,6 +152,12 @@ DEF2(ext16s_i64, 1, 1, 0, 0) #ifdef TCG_TARGET_HAS_ext32s_i64 DEF2(ext32s_i64, 1, 1, 0, 0) #endif +#ifdef TCG_TARGET_HAS_bswap16_i64 +DEF2(bswap16_i64, 1, 1, 0, 0) +#endif +#ifdef TCG_TARGET_HAS_bswap32_i64 +DEF2(bswap32_i64, 1, 1, 0, 0) +#endif #ifdef TCG_TARGET_HAS_bswap64_i64 DEF2(bswap64_i64, 1, 1, 0, 0) #endif