Message ID | 20210614083800.1166166-4-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | tcg: bswap improvements | expand |
On Mon, 14 Jun 2021 at 09:41, Richard Henderson <richard.henderson@linaro.org> wrote: > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > tcg/aarch64/tcg-target.c.inc | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc > index 27cde314a9..f72218b036 100644 > --- a/tcg/aarch64/tcg-target.c.inc > +++ b/tcg/aarch64/tcg-target.c.inc > @@ -2187,12 +2187,24 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, > tcg_out_rev64(s, a0, a1); > break; > case INDEX_op_bswap32_i64: > + tcg_out_rev32(s, a0, a1); > + if (a2 & TCG_BSWAP_OS) { > + tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a0); > + } Side note: it's rather confusing that tcg_out_rev32() doesn't emit a REV32 insn (it emits REV with sf==0). > + break; > case INDEX_op_bswap32_i32: > tcg_out_rev32(s, a0, a1); > break; > case INDEX_op_bswap16_i64: > case INDEX_op_bswap16_i32: > tcg_out_rev16(s, a0, a1); > + if (a2 & TCG_BSWAP_OS) { > + /* Output must be sign-extended. */ > + tcg_out_sxt(s, ext, MO_16, a0, a0); > + } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { > + /* Output must be zero-extended, but input isn't. */ > + tcg_out_uxt(s, MO_16, a0, a0); > + } > break; Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM
On 6/21/21 7:01 AM, Peter Maydell wrote: > On Mon, 14 Jun 2021 at 09:41, Richard Henderson > <richard.henderson@linaro.org> wrote: >> >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >> --- >> tcg/aarch64/tcg-target.c.inc | 12 ++++++++++++ >> 1 file changed, 12 insertions(+) >> >> diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc >> index 27cde314a9..f72218b036 100644 >> --- a/tcg/aarch64/tcg-target.c.inc >> +++ b/tcg/aarch64/tcg-target.c.inc >> @@ -2187,12 +2187,24 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, >> tcg_out_rev64(s, a0, a1); >> break; >> case INDEX_op_bswap32_i64: >> + tcg_out_rev32(s, a0, a1); >> + if (a2 & TCG_BSWAP_OS) { >> + tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a0); >> + } > > Side note: it's rather confusing that tcg_out_rev32() doesn't > emit a REV32 insn (it emits REV with sf==0). Mm, yes. I'll tidy that up in a separate patch. r~
On 6/21/21 7:01 AM, Peter Maydell wrote: > Side note: it's rather confusing that tcg_out_rev32() doesn't > emit a REV32 insn (it emits REV with sf==0). Which is REV with SF=0 also has OPC=10, which is REV32. So I think it's a simple case of the assembly mnemonics not matching up with the machine instructions as nicely as all that. r~
On Mon, 21 Jun 2021 at 19:12, Richard Henderson <richard.henderson@linaro.org> wrote: > > On 6/21/21 7:01 AM, Peter Maydell wrote: > > Side note: it's rather confusing that tcg_out_rev32() doesn't > > emit a REV32 insn (it emits REV with sf==0). > > Which is REV with SF=0 also has OPC=10, which is REV32. No, REV32 has SF=1. The two operations are different: REV <Wd>, <Wn> -- swaps byte order of the bottom 32 bits (zeroes the top half of Xd, as usual for Wn ops) REV32 <Xd>, <Xn> -- swaps byte order of bottom 32 bits and also swaps byte order of top 32 bits (ie it is a 64-bit to 64-bit operation which does does two bswap32()s) -- PMM
On 6/21/21 12:40 PM, Peter Maydell wrote: > On Mon, 21 Jun 2021 at 19:12, Richard Henderson > <richard.henderson@linaro.org> wrote: >> >> On 6/21/21 7:01 AM, Peter Maydell wrote: >>> Side note: it's rather confusing that tcg_out_rev32() doesn't >>> emit a REV32 insn (it emits REV with sf==0). >> >> Which is REV with SF=0 also has OPC=10, which is REV32. > > No, REV32 has SF=1. The two operations are different: > > REV <Wd>, <Wn> -- swaps byte order of the bottom 32 bits > (zeroes the top half of Xd, as usual for Wn ops) > REV32 <Xd>, <Xn> -- swaps byte order of bottom 32 bits and > also swaps byte order of top 32 bits > (ie it is a 64-bit to 64-bit operation > which does does two bswap32()s) Ignore the assembler mnemonic and look at the opcode: REV Wd,Wn = SF=0, OPC=10 REV32 Xd,Xn = SF=1, OPC=10 REV Xd,Xn = SF=1, OPC=11 REV(Wd,Wd) = (uint32_t)REV32(Xd,Xd) i.e. the usual interpretation of sf=0. r~
On Mon, 21 Jun 2021 at 20:50, Richard Henderson <richard.henderson@linaro.org> wrote: > > On 6/21/21 12:40 PM, Peter Maydell wrote: > > On Mon, 21 Jun 2021 at 19:12, Richard Henderson > > <richard.henderson@linaro.org> wrote: > >> > >> On 6/21/21 7:01 AM, Peter Maydell wrote: > >>> Side note: it's rather confusing that tcg_out_rev32() doesn't > >>> emit a REV32 insn (it emits REV with sf==0). > >> > >> Which is REV with SF=0 also has OPC=10, which is REV32. > > > > No, REV32 has SF=1. The two operations are different: > > > > REV <Wd>, <Wn> -- swaps byte order of the bottom 32 bits > > (zeroes the top half of Xd, as usual for Wn ops) > > REV32 <Xd>, <Xn> -- swaps byte order of bottom 32 bits and > > also swaps byte order of top 32 bits > > (ie it is a 64-bit to 64-bit operation > > which does does two bswap32()s) > > Ignore the assembler mnemonic and look at the opcode: ...but the point is that tcg_out_rev32() is not doing the thing that the assembler insn REV32 does, so ignoring the mnemonic is missing the point. > REV Wd,Wn = SF=0, OPC=10 > REV32 Xd,Xn = SF=1, OPC=10 > REV Xd,Xn = SF=1, OPC=11 > > REV(Wd,Wd) = (uint32_t)REV32(Xd,Xd) > i.e. the usual interpretation of sf=0. You could look at it that way, but that's not the way the insn mnemonics have been defined... -- PMM
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index 27cde314a9..f72218b036 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -2187,12 +2187,24 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_rev64(s, a0, a1); break; case INDEX_op_bswap32_i64: + tcg_out_rev32(s, a0, a1); + if (a2 & TCG_BSWAP_OS) { + tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a0); + } + break; case INDEX_op_bswap32_i32: tcg_out_rev32(s, a0, a1); break; case INDEX_op_bswap16_i64: case INDEX_op_bswap16_i32: tcg_out_rev16(s, a0, a1); + if (a2 & TCG_BSWAP_OS) { + /* Output must be sign-extended. */ + tcg_out_sxt(s, ext, MO_16, a0, a0); + } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { + /* Output must be zero-extended, but input isn't. */ + tcg_out_uxt(s, MO_16, a0, a0); + } break; case INDEX_op_ext8s_i64:
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- tcg/aarch64/tcg-target.c.inc | 12 ++++++++++++ 1 file changed, 12 insertions(+) -- 2.25.1