diff options
author | Ilya Leoshkevich <iii@linux.ibm.com> | 2018-09-24 15:01:57 +0000 |
---|---|---|
committer | Ilya Leoshkevich <iii@gcc.gnu.org> | 2018-09-24 15:01:57 +0000 |
commit | 882c3f17b61fffed412c19753c3b71b3c270b72f (patch) | |
tree | f8015d3556c0e8b04bfd0986b572c065db185264 /gcc/recog.h | |
parent | 9a51c0cc2af361d9338965d41d40ce8f8ede5266 (diff) | |
download | gcc-882c3f17b61fffed412c19753c3b71b3c270b72f.zip gcc-882c3f17b61fffed412c19753c3b71b3c270b72f.tar.gz gcc-882c3f17b61fffed412c19753c3b71b3c270b72f.tar.bz2 |
Change EQ_ATTR_ALT to support up to 64 alternatives
On S/390 there is a need to support more than 32 instruction
alternatives per define_insn. Currently this is not explicitly
prohibited or unsupported: MAX_RECOG_ALTERNATIVES is equal 35, and,
futhermore, the related code uses uint64_t for bitmaps in most places.
However, genattrtab contains the logic to convert (eq_attr "attribute"
"value") RTXs to (eq_attr_alt bitmap) RTXs, where bitmap contains
alternatives, whose "attribute" has the corresponding "value".
Unfortunately, bitmap is only 32 bits.
When adding the 33rd alternative, this led to (eq_attr "type" "larl")
becoming (eq_attr_alt -1050625 1), where -1050625 == 0xffeff7ff. The
cleared bits 12, 21 and 32 correspond to two existing and one newly
added insn of type "larl". compute_alternative_mask sign extended this
to 0xffffffffffeff7ff, which contained non-existent alternatives, and
this made simplify_test_exp fail with "invalid alternative specified".
I'm not sure why it didn't fail the same way before, since the top bit,
which led to sign extension, should have been set even with 32
alternatives. Maybe simplify_test_exp was not called for "type"
attribute for some reason?
This patch widens EQ_ATTR_ALT bitmap to 64 bits, making it possible to
gracefully handle up to 64 alternatives. It eliminates the problem with
the 33rd alternative on S/390.
gcc/ChangeLog:
2018-09-24 Ilya Leoshkevich <iii@linux.ibm.com>
* genattrtab.c (mk_attr_alt): Use alternative_mask.
(attr_rtx_1): Adjust caching to match the new EQ_ATTR_ALT field
types.
(check_attr_test): Use alternative_mask.
(get_attr_value): Likewise.
(compute_alternative_mask): Use alternative_mask and XWINT.
(make_alternative_compare): Use alternative_mask.
(attr_alt_subset_p): Use XWINT.
(attr_alt_subset_of_compl_p): Likewise.
(attr_alt_intersection): Use alternative_mask and XWINT.
(attr_alt_union): Likewise.
(attr_alt_complement): Use HOST_WIDE_INT and XWINT.
(mk_attr_alt): Use alternative_mask and HOST_WIDE_INT.
(simplify_test_exp): Use alternative_mask and XWINT.
(write_test_expr): Use alternative_mask and XWINT, adjust bit
number calculation to support 64 bits. Generate code that
checks 64-bit masks.
(main): Use alternative_mask.
* rtl.def (EQ_ATTR_ALT): Change field types from ii to ww.
From-SVN: r264537
Diffstat (limited to 'gcc/recog.h')
-rw-r--r-- | gcc/recog.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/gcc/recog.h b/gcc/recog.h index eca6280..3d417ea2 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see a type that has at least MAX_RECOG_ALTERNATIVES + 1 bits, with the extra bit giving an invalid value that can be used to mean "uninitialized". */ #define MAX_RECOG_ALTERNATIVES 35 -typedef uint64_t alternative_mask; +typedef uint64_t alternative_mask; /* Keep in sync with genattrtab.c. */ /* A mask of all alternatives. */ #define ALL_ALTERNATIVES ((alternative_mask) -1) |