Message ID | 20210614083800.1166166-14-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | tcg: bswap improvements | expand |
Hi Richard, On 6/14/21 10:37 AM, Richard Henderson wrote: > Merge tcg_out_bswap16 and tcg_out_bswap16s. Use the flags > in the internal uses for loads and stores. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > tcg/mips/tcg-target.c.inc | 60 ++++++++++++++++++--------------------- > 1 file changed, 28 insertions(+), 32 deletions(-) > > diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc > index 5944448b2a..7a5634419c 100644 > --- a/tcg/mips/tcg-target.c.inc > +++ b/tcg/mips/tcg-target.c.inc > @@ -540,39 +540,36 @@ static void tcg_out_movi(TCGContext *s, TCGType type, > } > } > > -static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg) > +static void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg, int flags) > { > + /* ret and arg can't be register tmp0 */ > + tcg_debug_assert(ret != TCG_TMP0); > + tcg_debug_assert(arg != TCG_TMP0); > + > if (use_mips32r2_instructions) { > tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg); > - } else { > - /* ret and arg can't be register at */ > - if (ret == TCG_TMP0 || arg == TCG_TMP0) { > - tcg_abort(); > + if (flags & TCG_BSWAP_OS) { > + tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret); > + } else if ((flags & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { > + tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xffff); > } > - > - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8); > - tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8); > - tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00); > - tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0); > + return; > } > -} > > -static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg) > -{ > - if (use_mips32r2_instructions) { > - tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg); > - tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret); > - } else { > - /* ret and arg can't be register at */ > - if (ret == TCG_TMP0 || arg == TCG_TMP0) { > - tcg_abort(); > - } > - > - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8); > + tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8); > + if (!(flags & TCG_BSWAP_IZ)) { > + tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, TCG_TMP0, 0x00ff); > + } > + if (flags & TCG_BSWAP_OS) { > tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24); > tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16); > - tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0); > + } else { > + tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8); > + if (flags & TCG_BSWAP_OZ) { > + tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00); > + } > } > + tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0); > } Do you mind including the comments (after reviewing them ;) )? static void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg, int flags) { /* ret and arg can't be register tmp0 */ tcg_debug_assert(ret != TCG_TMP0); tcg_debug_assert(arg != TCG_TMP0); /* src = abcd efgh */ if (use_mips32r2_instructions) { tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg); /* ret = cdab ghef */ if (flags & TCG_BSWAP_OS) { tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret); /* ret = ssss ghef */ } else if ((flags & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xffff); /* ret = 0000 ghef */ } return; } tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8); /* t0 = ssab cdef */ if (!(flags & TCG_BSWAP_IZ)) { /* t0 = 0000 00ef */ tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, TCG_TMP0, 0x00ff); } if (flags & TCG_BSWAP_OS) { tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24); /* ret = gh.. .... */ tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16); /* ret = ssss gh.. */ } else { tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8); /* ret = cdef gh.. */ if (flags & TCG_BSWAP_OZ) { /* ret = 0000 gh.. */ tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00); } } tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0); /* OZ: ret = 0000 ghef */ /* OS: ret = ssss ghef */ } Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
On 6/21/21 11:36 PM, Philippe Mathieu-Daudé wrote: > /* src = abcd > efgh */ > if (use_mips32r2_instructions) { > tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg); /* ret = cdab > ghef */ badc -- bytes swapped in halfwords. Also, this is a 32-bit insn, so 4 bytes is sufficient. > if (flags & TCG_BSWAP_OS) { > tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret); /* ret = ssss > ghef */ (ssss)ssdc Again, 32-bit insn, but implicitly sign-extending to 64-bits as per standard mips convention. > } else if ((flags & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == > TCG_BSWAP_OZ) { > tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xffff); > /* ret = 0000 > ghef */ (0000)00dc. > tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8); /* t0 = ssab > cdef */ > if (!(flags & TCG_BSWAP_IZ)) { /* t0 = 0000 > 00ef */ > tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, TCG_TMP0, 0x00ff); > } > if (flags & TCG_BSWAP_OS) { > tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24); /* ret = gh.. > .... */ > tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16); /* ret = ssss > gh.. */ > } else { > tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8); /* ret = cdef > gh.. */ > if (flags & TCG_BSWAP_OZ) { /* ret = 0000 > gh.. */ > tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00); > } > } > tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0); /* OZ: ret = 0000 > ghef */ > /* OS: ret = ssss > ghef */ Something like that, yes. I'll fix it up. r~
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 5944448b2a..7a5634419c 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -540,39 +540,36 @@ static void tcg_out_movi(TCGContext *s, TCGType type, } } -static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg) +static void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg, int flags) { + /* ret and arg can't be register tmp0 */ + tcg_debug_assert(ret != TCG_TMP0); + tcg_debug_assert(arg != TCG_TMP0); + if (use_mips32r2_instructions) { tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg); - } else { - /* ret and arg can't be register at */ - if (ret == TCG_TMP0 || arg == TCG_TMP0) { - tcg_abort(); + if (flags & TCG_BSWAP_OS) { + tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret); + } else if ((flags & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { + tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xffff); } - - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8); - tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8); - tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00); - tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0); + return; } -} -static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg) -{ - if (use_mips32r2_instructions) { - tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg); - tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret); - } else { - /* ret and arg can't be register at */ - if (ret == TCG_TMP0 || arg == TCG_TMP0) { - tcg_abort(); - } - - tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8); + tcg_out_opc_sa(s, OPC_SRL, TCG_TMP0, arg, 8); + if (!(flags & TCG_BSWAP_IZ)) { + tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, TCG_TMP0, 0x00ff); + } + if (flags & TCG_BSWAP_OS) { tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24); tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16); - tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0); + } else { + tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8); + if (flags & TCG_BSWAP_OZ) { + tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00); + } } + tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP0); } static void tcg_out_bswap_subr(TCGContext *s, const tcg_insn_unit *sub) @@ -1367,14 +1364,14 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi, break; case MO_UW | MO_BSWAP: tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0); - tcg_out_bswap16(s, lo, TCG_TMP1); + tcg_out_bswap16(s, lo, TCG_TMP1, TCG_BSWAP_IZ | TCG_BSWAP_OZ); break; case MO_UW: tcg_out_opc_imm(s, OPC_LHU, lo, base, 0); break; case MO_SW | MO_BSWAP: tcg_out_opc_imm(s, OPC_LHU, TCG_TMP1, base, 0); - tcg_out_bswap16s(s, lo, TCG_TMP1); + tcg_out_bswap16(s, lo, TCG_TMP1, TCG_BSWAP_IZ | TCG_BSWAP_OS); break; case MO_SW: tcg_out_opc_imm(s, OPC_LH, lo, base, 0); @@ -1514,8 +1511,7 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi, break; case MO_16 | MO_BSWAP: - tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, lo, 0xffff); - tcg_out_bswap16(s, TCG_TMP1, TCG_TMP1); + tcg_out_bswap16(s, TCG_TMP1, lo, 0); lo = TCG_TMP1; /* FALLTHRU */ case MO_16: @@ -1933,10 +1929,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_not_i64: i1 = OPC_NOR; goto do_unary; - case INDEX_op_bswap16_i32: - case INDEX_op_bswap16_i64: - i1 = OPC_WSBH; - goto do_unary; case INDEX_op_ext8s_i32: case INDEX_op_ext8s_i64: i1 = OPC_SEB; @@ -1948,6 +1940,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_opc_reg(s, i1, a0, TCG_REG_ZERO, a1); break; + case INDEX_op_bswap16_i32: + case INDEX_op_bswap16_i64: + tcg_out_bswap16(s, a0, a1, a2); + break; case INDEX_op_bswap32_i32: tcg_out_bswap32(s, a0, a1); break;
Merge tcg_out_bswap16 and tcg_out_bswap16s. Use the flags in the internal uses for loads and stores. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- tcg/mips/tcg-target.c.inc | 60 ++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 32 deletions(-) -- 2.25.1