[Bug target/64345] New: [SH] Improve single bit extraction
olegendo at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Dec 17 22:21:00 GMT 2014
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.
More information about the Gcc-bugs
mailing list