On Sun, Jul 14, 2024 at 4:05 AM Takayuki 'January June' Suwa
<jjsuwa_sys3...@yahoo.co.jp> wrote:
>
> [U]FLOAT.S machine instruction in Xtensa ISA, which converts an integer to
> a hardware single-precision FP register, has the ability to divide the
> result by power of two (0 to 15th).
>
> Similarly, [U]TRUNC.S instruction, which truncates single-precision FP to
> integer, can multiply the source value by power of two in advance, but
> neither of these currently uses this function (always specified with 0th
> power of two, i.e. a scaling factor of 1).
>
> This patch unleashes the scaling ability of the above instructions.
>
>      /* example */
>      float test0(int a) {
>        return a / 2.f;
>      }
>      float test1(unsigned int a) {
>        return a / 32768.f;
>      }
>      int test2(float a) {
>        return a * 2;
>      }
>      unsigned int test3(float a) {
>        return a * 32768;
>      }
>
>      ;; before
>      test0:
>         movi.n  a9, 0x3f
>         float.s f0, a2, 0
>         slli    a9, a9, 24
>         wfr     f1, a9
>         mul.s   f0, f0, f1
>         rfr     a2, f0
>         ret.n
>      test1:
>         movi.n  a9, 7
>         ufloat.s        f0, a2, 0
>         slli    a9, a9, 27
>         wfr     f1, a9
>         mul.s   f0, f0, f1
>         rfr     a2, f0
>         ret.n
>      test2:
>         wfr     f1, a2
>         add.s   f0, f1, f1
>         trunc.s a2, f0, 0
>         ret.n
>      test3:
>         movi.n  a9, 0x47
>         slli    a9, a9, 24
>         wfr     f1, a2
>         wfr     f2, a9
>         mul.s   f0, f1, f2
>         utrunc.s        a2, f0, 0
>         ret.n
>
>      ;; after
>      test0:
>         float.s f0, a2, 1
>         rfr     a2, f0
>         ret.n
>      test1:
>         ufloat.s        f0, a2, 15
>         rfr     a2, f0
>         ret.n
>      test2:
>         wfr     f0, a2
>         trunc.s a2, f0, 1
>         ret.n
>      test3:
>         wfr     f0, a2
>         utrunc.s        a2, f0, 15
>         ret.n
>
> gcc/ChangeLog:
>
>         * config/xtensa/predicates.md
>         (fix_scaling_operand, float_scaling_operand): New predicates.
>         * config/xtensa/xtensa.md
>         (any_fix/m_fix/s_fix, any_float/m_float/s_float):
>         New code iterators and their attributes.
>         (fix<s_fix>_truncsfsi2): Change from "fix_truncsfsi2".
>         (*fix<s_fix>_truncsfsi2_2x, *fix<s_fix>_truncsfsi2_scaled):
>         New insn definitions.
>         (float<s_float>sisf2): Change from "floatsisf2".
>         (*float<s_float>sisf2_scaled): New insn definition.
> ---
>   gcc/config/xtensa/predicates.md | 20 ++++++++++++
>   gcc/config/xtensa/xtensa.md     | 58 ++++++++++++++++++++++++++-------
>   2 files changed, 66 insertions(+), 12 deletions(-)

Regtested for target=xtensa-linux-uclibc, no new regressions.
Committed to master

-- 
Thanks.
-- Max

Reply via email to