]> git.ipfire.org Git - thirdparty/gcc.git/commit
xtensa: Make use of scaled [U]FLOAT/TRUNC.S instructions
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Sun, 14 Jul 2024 11:04:15 +0000 (20:04 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Tue, 30 Jul 2024 00:06:36 +0000 (17:06 -0700)
commitf9c7775f58798a051b57356ad321b758a2ee837d
treeaaa45e12584a12c354ce262651618ef91cfc3a7b
parent56c4979dd8be40681f2724861fc41ae6135e1e78
xtensa: Make use of scaled [U]FLOAT/TRUNC.S instructions

[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
gcc/config/xtensa/xtensa.md