tree-ssa-math-opts.c (find_bswap_or_nop): Zero out bytes in cmpxchg and cmpnop in two steps...
2016-11-14 Thomas Preud'homme <thomas.preudhomme@arm.com> gcc/ * tree-ssa-math-opts.c (find_bswap_or_nop): Zero out bytes in cmpxchg and cmpnop in two steps: first the ones not accessed in original gimple expression in a endian independent way and then the ones not accessed in the final result in an endian-specific way. (bswap_replace): Stop doing big endian adjustment. From-SVN: r242394
This commit is contained in:
parent
d32e1fd8b9
commit
bf166718a9
@ -1,3 +1,11 @@
|
||||
2016-11-14 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
* tree-ssa-math-opts.c (find_bswap_or_nop): Zero out bytes in cmpxchg
|
||||
and cmpnop in two steps: first the ones not accessed in original gimple
|
||||
expression in a endian independent way and then the ones not accessed
|
||||
in the final result in an endian-specific way.
|
||||
(bswap_replace): Stop doing big endian adjustment.
|
||||
|
||||
2016-11-14 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* config/i386/i386.md (*andndi3_doubleword): Merge operand constraints.
|
||||
|
@ -2504,9 +2504,11 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
|
||||
static gimple *
|
||||
find_bswap_or_nop (gimple *stmt, struct symbolic_number *n, bool *bswap)
|
||||
{
|
||||
/* The number which the find_bswap_or_nop_1 result should match in order
|
||||
to have a full byte swap. The number is shifted to the right
|
||||
according to the size of the symbolic number before using it. */
|
||||
unsigned rsize;
|
||||
uint64_t tmpn, mask;
|
||||
/* The number which the find_bswap_or_nop_1 result should match in order
|
||||
to have a full byte swap. The number is shifted to the right
|
||||
according to the size of the symbolic number before using it. */
|
||||
uint64_t cmpxchg = CMPXCHG;
|
||||
uint64_t cmpnop = CMPNOP;
|
||||
|
||||
@ -2527,28 +2529,38 @@ find_bswap_or_nop (gimple *stmt, struct symbolic_number *n, bool *bswap)
|
||||
|
||||
/* Find real size of result (highest non-zero byte). */
|
||||
if (n->base_addr)
|
||||
{
|
||||
unsigned HOST_WIDE_INT rsize;
|
||||
uint64_t tmpn;
|
||||
for (tmpn = n->n, rsize = 0; tmpn; tmpn >>= BITS_PER_MARKER, rsize++);
|
||||
else
|
||||
rsize = n->range;
|
||||
|
||||
for (tmpn = n->n, rsize = 0; tmpn; tmpn >>= BITS_PER_MARKER, rsize++);
|
||||
if (BYTES_BIG_ENDIAN && n->range != rsize)
|
||||
/* This implies an offset, which is currently not handled by
|
||||
bswap_replace. */
|
||||
return NULL;
|
||||
n->range = rsize;
|
||||
}
|
||||
|
||||
/* Zero out the extra bits of N and CMP*. */
|
||||
/* Zero out the bits corresponding to untouched bytes in original gimple
|
||||
expression. */
|
||||
if (n->range < (int) sizeof (int64_t))
|
||||
{
|
||||
uint64_t mask;
|
||||
|
||||
mask = ((uint64_t) 1 << (n->range * BITS_PER_MARKER)) - 1;
|
||||
cmpxchg >>= (64 / BITS_PER_MARKER - n->range) * BITS_PER_MARKER;
|
||||
cmpnop &= mask;
|
||||
}
|
||||
|
||||
/* Zero out the bits corresponding to unused bytes in the result of the
|
||||
gimple expression. */
|
||||
if (rsize < n->range)
|
||||
{
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
mask = ((uint64_t) 1 << (rsize * BITS_PER_MARKER)) - 1;
|
||||
cmpxchg &= mask;
|
||||
cmpnop >>= (n->range - rsize) * BITS_PER_MARKER;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = ((uint64_t) 1 << (rsize * BITS_PER_MARKER)) - 1;
|
||||
cmpxchg >>= (n->range - rsize) * BITS_PER_MARKER;
|
||||
cmpnop &= mask;
|
||||
}
|
||||
n->range = rsize;
|
||||
}
|
||||
|
||||
/* A complete byte swap should make the symbolic number to start with
|
||||
the largest digit in the highest order byte. Unchanged symbolic
|
||||
number indicates a read with same endianness as target architecture. */
|
||||
@ -2636,26 +2648,6 @@ bswap_replace (gimple *cur_stmt, gimple *src_stmt, tree fndecl,
|
||||
HOST_WIDE_INT load_offset = 0;
|
||||
|
||||
align = get_object_alignment (src);
|
||||
/* If the new access is smaller than the original one, we need
|
||||
to perform big endian adjustment. */
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
HOST_WIDE_INT bitsize, bitpos;
|
||||
machine_mode mode;
|
||||
int unsignedp, reversep, volatilep;
|
||||
tree offset;
|
||||
|
||||
get_inner_reference (src, &bitsize, &bitpos, &offset, &mode,
|
||||
&unsignedp, &reversep, &volatilep);
|
||||
if (n->range < (unsigned HOST_WIDE_INT) bitsize)
|
||||
{
|
||||
load_offset = (bitsize - n->range) / BITS_PER_UNIT;
|
||||
unsigned HOST_WIDE_INT l
|
||||
= (load_offset * BITS_PER_UNIT) & (align - 1);
|
||||
if (l)
|
||||
align = least_bit_hwi (l);
|
||||
}
|
||||
}
|
||||
|
||||
if (bswap
|
||||
&& align < GET_MODE_ALIGNMENT (TYPE_MODE (load_type))
|
||||
|
Loading…
x
Reference in New Issue
Block a user