This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/64345] New: [SH] Improve single bit extraction


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64345

            Bug ID: 64345
           Summary: [SH] Improve single bit extraction
           Product: gcc
           Version: 5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: olegendo at gcc dot gnu.org
            Target: sh*-*-*

Single bit extractions can be done through the T bit.
Some examples:

unsigned int test0 (unsigned int x)
{
  return ((x >> 4) ^ 1) & 1;
}

unsigned int test1 (unsigned int x)
{
  return ((x >> 4) & 1) ^ 1;
}

unsigned int test2 (unsigned int x)
{
  return ~(x >> 4) & 1;
}

now:
        mov     r4,r0
        shlr2   r0
        shlr2   r0
        xor     #1,r0
        and     #1,r0

non-sh2a:
        mov     r4,r0
        tst     #(1<<4),r0
        movt    r0

sh2a:
        bld     #4,r4
        movrt   r0


unsigned int test3 (unsigned int x)
{
  return ((~x >> 4) & 1);
}

now:
        not     r4,r4
        mov     r4,r0
        shlr2   r0
        shlr2   r0
        rts
        and     #1,r0

non-sh2a:
        mov     r4,r0
        tst     #(1<<4),r0
        movt    r0

sh2a:
        bld     #4,r4
        movrt   r0


unsigned int test4 (unsigned int x)
{
  return (x >> 4) & 1;
}

now:
        mov     r4,r0
        shlr2   r0
        shlr2   r0
        and     #1,r0

non-sh2:
        not     r4,r0
        tst     #(1<<4),r0
        movt    r0

sh2a (1):
        mov     r4,r0
        tst     #(1<<4),r0
        movrt   r0

sh2a (2)
        bld     #4,r4
        movt    r0


This can be realized by implementing zero_extract combine patterns such as:
set (reg:SI 170 [ D.1727 ])
    (zero_extract:SI (xor:SI (reg:SI 4 r4 [ x ])
            (const_int 16 [0x10]))
        (const_int 1 [0x1])
        (const_int 4 [0x4])))

Using the recently added support for multi-set patterns in combine, the T bit
contents can be described exactly, instead of simply T bit clobbers.

If the bit position is 0...7 the SH2A bld insn can be used.  For higher bit
positions it might be better to load a constant and use the tst rm,rn insn.  

Alternatively the reg can be shifted right via shlr8 and shlr16 before the tst
insn.  However, in this case it's probably better to use a shld + and #1,r0
sequence, if dynamic shifts are available.  Although that forces the result
value into r0, which might need to be moved into another reg.  With the tst
insn, r0 is used only as a temporary scratch register.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]